Merge branch 'main' of https://github.com/FreeCAD/FreeCAD into refactor
This commit is contained in:
47
.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
vendored
Normal file
47
.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<!--
|
||||
The FreeCAD community thanks you for your contribution!
|
||||
By creating a Pull Request you agree to the contributing policy. The complete policy can be found in the root of the source tree (CONTRIBUTING.md) or at https://github.com/FreeCAD/FreeCAD/blob/main/CONTRIBUTING.md
|
||||
|
||||
This template provides guidance on creating a PR that can be reviewed and approved as quickly as possible. Comments may be safely deleted.
|
||||
|
||||
Unless you know exactly what you're doing, please leave the checkbox 'Allow edits by maintainers' enabled. This will allow maintainers to help you.
|
||||
-->
|
||||
|
||||
## Description
|
||||
<!-- Include a brief summary of the changes. -->
|
||||
|
||||
## Issues
|
||||
<!-- link to individual issues this PR closes by referencing the issue number (e.g., fixes #1234, closes #4321). -->
|
||||
|
||||
## Before and After Images
|
||||
<!-- If your proposed changes affect the FreeCAD GUI, add before and after screenshots -->
|
||||
|
||||
|
||||
|
||||
<!-- Notes on the PR Review Process
|
||||
|
||||
The following section describes what the maintainers consider when reviewing your Pull Request. These items may not require you to take any action. This information is provided for context. Understanding what we consider will help you prepare your request for speedy approval.
|
||||
|
||||
You can find additional documentation about these guidelines in the [Developers handbook](https://freecad.github.io/DevelopersHandbook).
|
||||
|
||||
Alignment (Does the PR align with the goals and interests of the project?)
|
||||
- Does the PR have at least one issue linked, which this PR closes?
|
||||
- Has the conversation on the PR and related issue(s) reached consensus?
|
||||
- If the PR affects the GUI, is the Design Working Group (DWG) aware and have they had time to review and comment?
|
||||
- If the PR affects the GUI, did the contributor include before/after images?
|
||||
- If the PR affects standards and workflow, is the CAD Working Group (CWG) aware and have they had time to review/comment?
|
||||
|
||||
Impact (Does the change affect other parts of the project?)
|
||||
- Has the impact on documentation been considered and appropriate action taken?
|
||||
- Has the impact on translation been considered appropriate action taken?
|
||||
- Will the PR affect existing user documents?
|
||||
|
||||
Code Quality (Is code well-written and maintainable?)
|
||||
- Does the PR warrant a review by the Code Quality Working Group (CQWG)?
|
||||
- Does the change include tests?
|
||||
- Is the PR rebased on the current main branch with unnecessary commits squashed?
|
||||
|
||||
Release (Are there considerations related to release timing?)
|
||||
- Has the PR been considered for backporting to the latest release branch?
|
||||
- Have the release notes been considered/updated?
|
||||
-->
|
||||
11
.github/dependabot.yml
vendored
Normal file
11
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
|
||||
- package-ecosystem: pip
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
7
.github/workflows/CI_cleanup.yml
vendored
7
.github/workflows/CI_cleanup.yml
vendored
@@ -57,6 +57,11 @@ jobs:
|
||||
env:
|
||||
logdir: /tmp/log/
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Make needed directories
|
||||
run: |
|
||||
mkdir -p ${{ env.logdir }}
|
||||
@@ -103,7 +108,7 @@ jobs:
|
||||
done
|
||||
- name: Upload logs
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: ${{ github.job }}-Logs
|
||||
path: |
|
||||
|
||||
@@ -117,6 +117,13 @@ runs:
|
||||
testCommand: ${{ inputs.builddir }}/tests/Sketcher_tests_run --gtest_output=json:${{ inputs.reportdir }}spreadsheet_gtest_results.json
|
||||
testLogFile: ${{ inputs.reportdir }}spreadsheet_gtest_test_log.txt
|
||||
testName: Spreadsheet
|
||||
- name: C++ Start tests
|
||||
id: start
|
||||
uses: ./.github/workflows/actions/runCPPTests/runSingleTest
|
||||
with:
|
||||
testCommand: ${{ inputs.builddir }}/tests/Start_tests_run --gtest_output=json:${{ inputs.reportdir }}start_gtest_results.json
|
||||
testLogFile: ${{ inputs.reportdir }}start_gtest_test_log.txt
|
||||
testName: Start
|
||||
- name: Compose summary report based on test results
|
||||
if: always()
|
||||
shell: bash -l {0}
|
||||
|
||||
@@ -41,11 +41,11 @@ inputs:
|
||||
libpackdownloadurl:
|
||||
description: "URL where to download libpack"
|
||||
required: false
|
||||
default: https://github.com/FreeCAD/FreeCAD-LibPack/releases/download/3.1.0/LibPack-1.1.0-v3.1.0-Release.7z
|
||||
default: https://github.com/FreeCAD/FreeCAD-LibPack/releases/download/3.1.1.2/LibPack-1.1.0-v3.1.1.2-Release.7z
|
||||
libpackname:
|
||||
description: "Libpack name (once downloaded)"
|
||||
required: false
|
||||
default: LibPack-1.1.0-v3.1.0-Release
|
||||
default: LibPack-1.1.0-v3.1.1.2-Release
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
|
||||
@@ -20,9 +20,14 @@ jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: '🧹 Tag & close stale unconfirmed bugs'
|
||||
id: stale_issues
|
||||
uses: actions/stale@v9.1.0
|
||||
uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: -1
|
||||
@@ -49,7 +54,7 @@ jobs:
|
||||
|
||||
- name: '🧹 Close stale requested feedback issues'
|
||||
id: awaiting_issues
|
||||
uses: actions/stale@v9.1.0
|
||||
uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: -1
|
||||
@@ -77,7 +82,7 @@ jobs:
|
||||
|
||||
- name: '🧹 Tag & close inactive issues'
|
||||
id: inactive_issues
|
||||
uses: actions/stale@v9.1.0
|
||||
uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: -1
|
||||
@@ -108,7 +113,7 @@ jobs:
|
||||
|
||||
- name: '🧹 Tag & close inactive PRs'
|
||||
id: inactive_pr
|
||||
uses: actions/stale@v9.1.0
|
||||
uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: -1
|
||||
|
||||
27
.github/workflows/dependency-review.yml
vendored
Normal file
27
.github/workflows/dependency-review.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# Dependency Review Action
|
||||
#
|
||||
# This Action will scan dependency manifest files that change as part of a Pull Request,
|
||||
# surfacing known-vulnerable versions of the packages declared or updated in the PR.
|
||||
# Once installed, if the workflow run is marked as required,
|
||||
# PRs introducing known-vulnerable packages will be blocked from merging.
|
||||
#
|
||||
# Source repository: https://github.com/actions/dependency-review-action
|
||||
name: 'Dependency Review'
|
||||
on: [pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
dependency-review:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@67d4f4bd7a9b17a0db54d2a7519187c65e339de8 # v4
|
||||
9
.github/workflows/issue-metrics.yml
vendored
9
.github/workflows/issue-metrics.yml
vendored
@@ -16,6 +16,11 @@ jobs:
|
||||
|
||||
steps:
|
||||
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Get dates for last month
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -30,13 +35,13 @@ jobs:
|
||||
echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Run issue-metrics tool
|
||||
uses: github/issue-metrics@v3
|
||||
uses: github/issue-metrics@ed6e4b2b46f44ec7cdd2f6c145757a67a07ecf5b # v3.18.4
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SEARCH_QUERY: 'repo:FreeCAD/FreeCAD is:issue created:${{ env.last_month }}'
|
||||
|
||||
- name: Create issue
|
||||
uses: peter-evans/create-issue-from-file@v4
|
||||
uses: peter-evans/create-issue-from-file@e8ef132d6df98ed982188e460ebb3b5d4ef3a9cd # v5.0.1
|
||||
with:
|
||||
title: Monthly issue metrics report
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
10
.github/workflows/labeler.yml
vendored
10
.github/workflows/labeler.yml
vendored
@@ -9,6 +9,9 @@ on:
|
||||
pull_request_target:
|
||||
types: [opened, reopened]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
label:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -17,7 +20,12 @@ jobs:
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/labeler@v5
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
configuration-path: ".github/labels.yml"
|
||||
|
||||
81
.github/workflows/scorecards.yml
vendored
Normal file
81
.github/workflows/scorecards.yml
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
# This workflow uses actions that are not certified by GitHub. They are provided
|
||||
# by a third-party and are governed by separate terms of service, privacy
|
||||
# policy, and support documentation.
|
||||
|
||||
name: Scorecard supply-chain security
|
||||
on:
|
||||
# For Branch-Protection check. Only the default branch is supported. See
|
||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
|
||||
branch_protection_rule:
|
||||
# To guarantee Maintained check is occasionally updated. See
|
||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
|
||||
schedule:
|
||||
- cron: '20 7 * * 2'
|
||||
push:
|
||||
branches: ["main"]
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
analysis:
|
||||
name: Scorecard analysis
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# Needed to upload the results to code-scanning dashboard.
|
||||
security-events: write
|
||||
# Needed to publish results and get a badge (see publish_results below).
|
||||
id-token: write
|
||||
contents: read
|
||||
actions: read
|
||||
# To allow GraphQL ListCommits to work
|
||||
issues: read
|
||||
pull-requests: read
|
||||
# To detect SAST tools
|
||||
checks: read
|
||||
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
|
||||
# - you want to enable the Branch-Protection check on a *public* repository, or
|
||||
# - you are installing Scorecards on a *private* repository
|
||||
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
|
||||
# repo_token: ${{ secrets.SCORECARD_TOKEN }}
|
||||
|
||||
# Public repositories:
|
||||
# - Publish results to OpenSSF REST API for easy access by consumers
|
||||
# - Allows the repository to include the Scorecard badge.
|
||||
# - See https://github.com/ossf/scorecard-action#publishing-results.
|
||||
# For private repositories:
|
||||
# - `publish_results` will always be set to `false`, regardless
|
||||
# of the value entered here.
|
||||
publish_results: true
|
||||
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@45775bd8235c68ba998cffa5171334d58593da47 # v3.28.15
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
19
.github/workflows/sub_buildPixi.yml
vendored
19
.github/workflows/sub_buildPixi.yml
vendored
@@ -69,6 +69,11 @@ jobs:
|
||||
os: [windows-latest, ubuntu-latest, macos-latest]
|
||||
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Set Platform Environment Variables
|
||||
shell: bash -l {0}
|
||||
env:
|
||||
@@ -81,7 +86,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Add GCC Problem Matcher
|
||||
if: runner.os == 'Linux'
|
||||
@@ -106,13 +111,13 @@ jobs:
|
||||
mkdir -p ${{ env.reportdir }}
|
||||
echo "reportFile=${{ env.reportfilename }}" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: prefix-dev/setup-pixi@v0.8.3
|
||||
- uses: prefix-dev/setup-pixi@19eac09b398e3d0c747adc7921926a6d802df4da # v0.8.8
|
||||
with:
|
||||
pixi-version: v0.43.3
|
||||
pixi-version: v0.45.0
|
||||
cache: false
|
||||
|
||||
- name: Restore Compiler Cache
|
||||
uses: actions/cache/restore@v4
|
||||
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: FC-${{ env.cacheKey }}-${{ github.ref }}-${{ github.run_id }}
|
||||
@@ -195,14 +200,14 @@ jobs:
|
||||
|
||||
- name: Save Compiler Cache
|
||||
if: always()
|
||||
uses: actions/cache/save@v4
|
||||
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: FC-${{ env.cacheKey }}-${{ github.ref }}-${{ github.run_id }}
|
||||
|
||||
- name: Upload logs
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: ${{ inputs.artifactBasename }}-${{ matrix.os }}-Logs
|
||||
path: |
|
||||
@@ -211,7 +216,7 @@ jobs:
|
||||
|
||||
- name: Upload report
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: ${{ env.reportfilename }}
|
||||
path: |
|
||||
|
||||
17
.github/workflows/sub_buildUbuntu.yml
vendored
17
.github/workflows/sub_buildUbuntu.yml
vendored
@@ -71,8 +71,13 @@ jobs:
|
||||
reportFile: ${{ steps.Init.outputs.reportFile }}
|
||||
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checking out source code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Install FreeCAD dependencies
|
||||
@@ -94,7 +99,7 @@ jobs:
|
||||
compiler: ${{ env.CXX }}
|
||||
qt_major_version: 5
|
||||
- name: Restore Compiler Cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
with:
|
||||
save-always: true
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
@@ -107,6 +112,10 @@ jobs:
|
||||
ccache -s
|
||||
ccache -z
|
||||
ccache -p
|
||||
- name: Install cmake
|
||||
uses: jwlawson/actions-setup-cmake@802fa1a2c4e212495c05bf94dba2704a92a472be # v2.0.2
|
||||
with:
|
||||
cmake-version: '3.31.6'
|
||||
- name: CMake Configure
|
||||
uses: ./.github/workflows/actions/linux/configure
|
||||
with:
|
||||
@@ -175,7 +184,7 @@ jobs:
|
||||
reportFile: ${{env.reportdir}}${{ env.reportfilename }}
|
||||
- name: Upload logs
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: ${{ inputs.artifactBasename }}-Logs
|
||||
path: |
|
||||
@@ -183,7 +192,7 @@ jobs:
|
||||
/var/crash/*FreeCAD*
|
||||
- name: Upload report
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: ${{ env.reportfilename }}
|
||||
path: |
|
||||
|
||||
17
.github/workflows/sub_buildWindows.yml
vendored
17
.github/workflows/sub_buildWindows.yml
vendored
@@ -62,8 +62,13 @@ jobs:
|
||||
reportFile: ${{ steps.Init.outputs.reportFile }}
|
||||
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checking out source code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Make needed directories, files and initializations
|
||||
@@ -85,7 +90,7 @@ jobs:
|
||||
with:
|
||||
libpackdir: ${{ env.libpackdir }}
|
||||
- name: Restore compiler cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
with:
|
||||
save-always: true
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
@@ -98,6 +103,10 @@ jobs:
|
||||
. $env:ccachebindir\ccache -s
|
||||
. $env:ccachebindir\ccache -z
|
||||
. $env:ccachebindir\ccache -p
|
||||
- name: Install cmake
|
||||
uses: jwlawson/actions-setup-cmake@802fa1a2c4e212495c05bf94dba2704a92a472be # v2.0.2
|
||||
with:
|
||||
cmake-version: '3.31.6'
|
||||
- name: Configuring CMake
|
||||
run: >
|
||||
cmake -B"${{ env.builddir }}" .
|
||||
@@ -111,7 +120,7 @@ jobs:
|
||||
-DFREECAD_COPY_LIBPACK_BIN_TO_BUILD=ON
|
||||
-DFREECAD_COPY_PLUGINS_BIN_TO_BUILD=ON
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2.0.0
|
||||
- name: Compiling sources
|
||||
run: |
|
||||
cd $env:builddir
|
||||
@@ -129,7 +138,7 @@ jobs:
|
||||
. ${{ env.builddir }}\bin\FreeCADCmd -t 0 # 2>&1 | tee -filepath ${{ env.logdir }}\integrationTests.log
|
||||
- name: Upload logs
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: ${{ inputs.artifactBasename }}-Logs
|
||||
path: |
|
||||
|
||||
16
.github/workflows/sub_lint.yml
vendored
16
.github/workflows/sub_lint.yml
vendored
@@ -121,7 +121,7 @@ on:
|
||||
type: string
|
||||
required: false
|
||||
spellingIgnore:
|
||||
default: ./.git,*.po,*.ts,*.svg,./ChangeLog.txt,./src/3rdParty,./src/Mod/Assembly/App/opendcm,./src/Base/swig*,./src/Mod/Robot/App/kdl_cp,./src/Mod/Import/App/SCL*,./src/WindowsInstaller,./src/Doc/FreeCAD.uml,./build/
|
||||
default: ./.git*,*.po,*.ts,*.svg,./src/3rdParty,./src/Base/swig*,./src/Mod/Robot/App/kdl_cp,./src/Mod/Import/App/SCL*,./src/Doc/FreeCAD.uml,./build/
|
||||
type: string
|
||||
required: false
|
||||
codespellFailSilent:
|
||||
@@ -168,6 +168,9 @@ on:
|
||||
reportFile:
|
||||
value: ${{ jobs.Lint.outputs.reportFile }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
Lint:
|
||||
@@ -185,8 +188,13 @@ jobs:
|
||||
reportFile: ${{ steps.Init.outputs.reportFile }}
|
||||
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
@@ -335,7 +343,7 @@ jobs:
|
||||
|
||||
- name: Upload logs and fixes
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: ${{ inputs.artifactBasename }}-Logs
|
||||
path: |
|
||||
@@ -344,7 +352,7 @@ jobs:
|
||||
|
||||
- name: Upload report
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: ${{ env.reportfilename }}
|
||||
path: |
|
||||
|
||||
9
.github/workflows/sub_prepare.yml
vendored
9
.github/workflows/sub_prepare.yml
vendored
@@ -71,6 +71,11 @@ jobs:
|
||||
changedCppFiles: ${{ steps.Output.outputs.changedCppFiles }}
|
||||
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Make needed directories, files and initializations
|
||||
id: Init
|
||||
run: |
|
||||
@@ -148,14 +153,14 @@ jobs:
|
||||
echo "" >> $GITHUB_OUTPUT
|
||||
- name: Upload logs
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: ${{ inputs.artifactBasename }}-Logs
|
||||
path: |
|
||||
${{ env.logdir }}
|
||||
- name: Upload report
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: ${{ env.reportfilename }}
|
||||
path: |
|
||||
|
||||
160
.github/workflows/sub_weeklyBuild.yml
vendored
Normal file
160
.github/workflows/sub_weeklyBuild.yml
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
name: Weekly Build
|
||||
on:
|
||||
schedule:
|
||||
- cron: "42 18 * * 1"
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
tag_build:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
build_tag: ${{ steps.tag_build.outputs.build_tag }}
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
fetch-depth: 2
|
||||
submodules: 'recursive'
|
||||
|
||||
- name: Tag Build
|
||||
id: tag_build
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
export BUILD_TAG=weekly-$(date "+%Y.%m.%d")
|
||||
echo "BUILD_TAG=${BUILD_TAG}" >> "$GITHUB_ENV"
|
||||
echo "build_tag=${BUILD_TAG}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload Source
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
python3 package/rattler-build/scripts/make_version_file.py ../freecad_version.txt
|
||||
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
|
||||
git config user.name 'github-actions[bot]'
|
||||
git apply package/rattler-build/scripts/disable_git_info.patch
|
||||
git commit -a -m "Disable git info write to Version.h"
|
||||
git archive HEAD -o freecad_source_${BUILD_TAG}.tar
|
||||
git submodule foreach --recursive \
|
||||
"git archive HEAD --prefix=\$path/ -o \$sha1.tar && \
|
||||
tar -A -f \$toplevel/freecad_source_${BUILD_TAG}.tar \$sha1.tar && \
|
||||
rm \$sha1.tar"
|
||||
gzip freecad_source_${BUILD_TAG}.tar
|
||||
sha256sum freecad_source_${BUILD_TAG}.tar.gz > freecad_source_${BUILD_TAG}.tar.gz-SHA256.txt
|
||||
gh release create ${BUILD_TAG} --title "Weekly Build ${BUILD_TAG}" --notes "Weekly Build ${BUILD_TAG}" --prerelease || true
|
||||
gh release upload --clobber ${BUILD_TAG} "freecad_source_${BUILD_TAG}.tar.gz" "freecad_source_${BUILD_TAG}.tar.gz-SHA256.txt"
|
||||
|
||||
build:
|
||||
needs: tag_build
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- { target: linux-64, os: ubuntu-22.04 }
|
||||
- { target: linux-arm64, os: ubuntu-22.04-arm }
|
||||
- { target: osx-64, os: macos-13 }
|
||||
- { target: osx-arm64, os: macos-latest }
|
||||
- { target: win-64, os: windows-latest }
|
||||
fail-fast: false
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
environment: weekly-build
|
||||
steps:
|
||||
# prevent running out of disk space on Ubuntu runners.
|
||||
- name: Maximize build space
|
||||
if: runner.os == 'Linux'
|
||||
uses: AdityaGarg8/remove-unwanted-software@v5
|
||||
with:
|
||||
verbose: 'true'
|
||||
remove-android: 'true' # (frees ~9 GB)
|
||||
remove-cached-tools: 'true' # (frees ~8.3 GB)
|
||||
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Set Platform Environment Variables
|
||||
shell: bash -l {0}
|
||||
env:
|
||||
BUILD_TAG: ${{ needs.tag_build.outputs.build_tag }}
|
||||
OPERATING_SYSTEM: ${{ runner.os }}
|
||||
run: |
|
||||
echo "BUILD_TAG=${BUILD_TAG}" >> "$GITHUB_ENV"
|
||||
if [[ $OPERATING_SYSTEM == 'Windows' ]]; then
|
||||
echo 'PIXI_CACHE_DIR=D:\rattler' >> "$GITHUB_ENV"
|
||||
echo 'RATTLER_CACHE_DIR=D:\rattler' >> "$GITHUB_ENV"
|
||||
fi
|
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
submodules: 'recursive'
|
||||
|
||||
- uses: prefix-dev/setup-pixi@19eac09b398e3d0c747adc7921926a6d802df4da # v0.8.8
|
||||
with:
|
||||
pixi-version: v0.42.1
|
||||
cache: false
|
||||
|
||||
- name: Install the Apple certificate and provisioning profile
|
||||
if: runner.os == 'macOS'
|
||||
env:
|
||||
APP_SPECIFIC_PASSWORD: ${{ secrets.APP_SPECIFIC_PASSWORD }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
|
||||
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
|
||||
DEVELOPER_TEAM_ID: ${{ secrets.DEVELOPER_TEAM_ID }}
|
||||
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
||||
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
|
||||
run: |
|
||||
# create variables
|
||||
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
|
||||
PP_PATH=$RUNNER_TEMP/FreeCAD_Weekly.provisionprofile
|
||||
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
|
||||
|
||||
export KEYCHAIN_PASSWORD=$(openssl rand -base64 8)
|
||||
|
||||
# import certificate and provisioning profile from secrets
|
||||
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
|
||||
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
|
||||
|
||||
# create temporary keychain
|
||||
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
||||
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
|
||||
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
||||
|
||||
# import certificate to keychain
|
||||
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
|
||||
security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
||||
security list-keychain -d user -s $KEYCHAIN_PATH
|
||||
|
||||
# apply provisioning profile
|
||||
mkdir -p ~/Library/Provisioning\ Profiles
|
||||
cp $PP_PATH ~/Library/Provisioning\ Profiles
|
||||
|
||||
xcrun notarytool store-credentials "FreeCAD" --keychain "$KEYCHAIN_PATH" --apple-id "${APPLE_ID}" --password "${APP_SPECIFIC_PASSWORD}" --team-id "${DEVELOPER_TEAM_ID}"
|
||||
|
||||
- name: Build and Release Packages
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
SIGNING_KEY_ID: ${{ secrets.SIGNING_KEY_ID }}
|
||||
SIGN_RELEASE: "true"
|
||||
TARGET_PLATFORM: ${{ matrix.target }}
|
||||
UPLOAD_RELEASE: "true"
|
||||
run: |
|
||||
cd package/rattler-build
|
||||
pixi install
|
||||
pixi run -e package create_bundle
|
||||
|
||||
## Needed if running on a self-hosted runner:
|
||||
# - name: Clean up keychain and provisioning profile
|
||||
# if: ${{ always() }}
|
||||
# run: |
|
||||
# security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
|
||||
# rm ~/Library/MobileDevice/Provisioning\ Profiles/build_pp.mobileprovision
|
||||
12
.github/workflows/sub_wrapup.yml
vendored
12
.github/workflows/sub_wrapup.yml
vendored
@@ -39,6 +39,9 @@ on:
|
||||
type: string
|
||||
required: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
WrapUp:
|
||||
@@ -50,11 +53,16 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Make needed directories, files and initializations
|
||||
run: |
|
||||
mkdir -p ${{ env.artifactsDownloadDir }}
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
|
||||
with:
|
||||
path: ${{ env.artifactsDownloadDir }}
|
||||
- name: Save input data to file
|
||||
@@ -111,7 +119,7 @@ jobs:
|
||||
cat report.md >> $GITHUB_STEP_SUMMARY
|
||||
- name: Delete used artifacts
|
||||
continue-on-error: true
|
||||
uses: geekyeggo/delete-artifact@v5
|
||||
uses: geekyeggo/delete-artifact@f275313e70c08f6120db482d7a6b98377786765b # v5.1.0
|
||||
with:
|
||||
name: |
|
||||
${{ env.usedArtifacts }}
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -7,3 +7,6 @@
|
||||
[submodule "src/3rdParty/GSL"]
|
||||
path = src/3rdParty/GSL
|
||||
url = https://github.com/microsoft/GSL
|
||||
[submodule "src/Mod/AddonManager"]
|
||||
path = src/Mod/AddonManager
|
||||
url = https://github.com/FreeCAD/AddonManager.git
|
||||
|
||||
@@ -9,7 +9,6 @@ files: |
|
||||
src/Main|
|
||||
src/Tools|
|
||||
tests/src|
|
||||
src/Mod/AddonManager|
|
||||
src/Mod/Assembly|
|
||||
src/Mod/CAM|
|
||||
src/Mod/Cloud|
|
||||
|
||||
@@ -13,6 +13,18 @@
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
},
|
||||
"CMAKE_JOB_POOL_COMPILE": {
|
||||
"type": "STRING",
|
||||
"value": "compile_jobs"
|
||||
},
|
||||
"CMAKE_JOB_POOL_LINK": {
|
||||
"type": "STRING",
|
||||
"value": "link_jobs"
|
||||
},
|
||||
"CMAKE_POLICY_VERSION_MINIMUM": {
|
||||
"type": "STRING",
|
||||
"value": "3.5"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -59,6 +71,10 @@
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
},
|
||||
"BUILD_REVERSEENGINEERING": {
|
||||
"type": "BOOL",
|
||||
"value": "OFF"
|
||||
},
|
||||
"ENABLE_DEVELOPER_TESTS": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
@@ -87,6 +103,10 @@
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
},
|
||||
"FREECAD_QT_VERSION": {
|
||||
"type": "STRING",
|
||||
"value": "6"
|
||||
},
|
||||
"OCCT_CMAKE_FALLBACK": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
@@ -107,26 +127,30 @@
|
||||
},
|
||||
"cmakeExecutable": "${sourceDir}/conda/cmake.sh",
|
||||
"cacheVariables": {
|
||||
"CMAKE_INCLUDE_PATH": {
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}/include"
|
||||
"CMAKE_C_COMPILER": {
|
||||
"type": "STRING",
|
||||
"value": "clang"
|
||||
},
|
||||
"CMAKE_INSTALL_LIBDIR": {
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}/lib"
|
||||
"CMAKE_CXX_COMPILER": {
|
||||
"type": "STRING",
|
||||
"value": "clang++"
|
||||
},
|
||||
"CMAKE_EXE_LINKER_FLAGS": {
|
||||
"type": "STRING",
|
||||
"value": "-fuse-ld=mold"
|
||||
},
|
||||
"CMAKE_INSTALL_PREFIX": {
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}"
|
||||
},
|
||||
"CMAKE_LIBRARY_PATH":{
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}/lib"
|
||||
},
|
||||
"CMAKE_PREFIX_PATH": {
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}"
|
||||
},
|
||||
"CMAKE_SHARED_LINKER_FLAGS": {
|
||||
"type": "STRING",
|
||||
"value": "-fuse-ld=mold"
|
||||
},
|
||||
"OCC_INCLUDE_DIR": {
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}/include/opencascade"
|
||||
@@ -147,22 +171,10 @@
|
||||
"type": "STRING",
|
||||
"value": "/opt/homebrew;/usr/local/homebrew"
|
||||
},
|
||||
"CMAKE_INCLUDE_PATH": {
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}/include"
|
||||
},
|
||||
"CMAKE_INSTALL_LIBDIR": {
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}/lib"
|
||||
},
|
||||
"CMAKE_INSTALL_PREFIX": {
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}"
|
||||
},
|
||||
"CMAKE_LIBRARY_PATH":{
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}/lib"
|
||||
},
|
||||
"CMAKE_PREFIX_PATH": {
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}"
|
||||
@@ -183,22 +195,10 @@
|
||||
},
|
||||
"cmakeExecutable": "${sourceDir}/conda/cmake.cmd",
|
||||
"cacheVariables": {
|
||||
"CMAKE_INCLUDE_PATH": {
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}/Library/include"
|
||||
},
|
||||
"CMAKE_INSTALL_LIBDIR": {
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}/Library/lib"
|
||||
},
|
||||
"CMAKE_INSTALL_PREFIX": {
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}/Library"
|
||||
},
|
||||
"CMAKE_LIBRARY_PATH":{
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}/Library/lib"
|
||||
},
|
||||
"CMAKE_PREFIX_PATH": {
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CONDA_PREFIX}/Library"
|
||||
|
||||
@@ -130,7 +130,7 @@ if (OCC_FOUND)
|
||||
else ()
|
||||
list(APPEND OCC_LIBRARIES TKDESTEP TKDEIGES TKDEGLTF TKDESTL)
|
||||
endif ()
|
||||
message(STATUS "-- Found OpenCASCADE version: ${OCC_VERSION_STRING}")
|
||||
message(STATUS "-- OpenCASCADE include directory: ${OCC_INCLUDE_DIR}")
|
||||
message(STATUS "-- OpenCASCADE shared libraries directory: ${OCC_LIBRARY_DIR}")
|
||||
message(STATUS "Found OpenCASCADE version: ${OCC_VERSION_STRING}")
|
||||
message(STATUS " OpenCASCADE include directory: ${OCC_INCLUDE_DIR}")
|
||||
message(STATUS " OpenCASCADE shared libraries directory: ${OCC_LIBRARY_DIR}")
|
||||
endif ()
|
||||
|
||||
@@ -28,6 +28,7 @@ macro(CheckInterModuleDependencies)
|
||||
REQUIRES_MODS(BUILD_MESH_PART BUILD_PART BUILD_MESH)
|
||||
REQUIRES_MODS(BUILD_FLAT_MESH BUILD_MESH_PART)
|
||||
REQUIRES_MODS(BUILD_OPENSCAD BUILD_MESH_PART BUILD_DRAFT)
|
||||
REQUIRES_MODS(BUILD_MATERIAL_EXTERNAL BUILD_MATERIAL)
|
||||
REQUIRES_MODS(BUILD_PART BUILD_MATERIAL)
|
||||
REQUIRES_MODS(BUILD_PART_DESIGN BUILD_SKETCHER)
|
||||
# REQUIRES_MODS(BUILD_CAM BUILD_PART BUILD_MESH BUILD_ROBOT)
|
||||
|
||||
@@ -9,6 +9,13 @@ macro(CompilerChecksAndSetups)
|
||||
|
||||
# ================================================================================
|
||||
|
||||
# Use a heuristic of 1 GiB of RAM needed per compiler job and limit to
|
||||
# a single link job. Modern linkers are multithreaded and running them concurrently
|
||||
# can exhaust resources.
|
||||
cmake_host_system_information(RESULT avail_mem_MiB QUERY TOTAL_PHYSICAL_MEMORY)
|
||||
math(EXPR max_compile_procs "${avail_mem_MiB} / 1024")
|
||||
set_property(GLOBAL PROPERTY JOB_POOLS compile_jobs=${max_compile_procs} link_jobs=1)
|
||||
|
||||
# Allow developers to use Boost < 1.74
|
||||
if (NOT BOOST_MIN_VERSION)
|
||||
set(BOOST_MIN_VERSION 1.74)
|
||||
|
||||
@@ -10,6 +10,7 @@ macro(InitializeFreeCADBuildOptions)
|
||||
option(FREECAD_USE_EXTERNAL_KDL "Use system installed orocos-kdl instead of the bundled." OFF)
|
||||
option(FREECAD_USE_EXTERNAL_FMT "Use system installed fmt library if available instead of fetching the source." ON)
|
||||
option(FREECAD_USE_EXTERNAL_ONDSELSOLVER "Use system installed OndselSolver instead of git submodule." OFF)
|
||||
option(FREECAD_USE_EXTERNAL_E57FORMAT "Use system installed libE57Format instead of the bundled." OFF)
|
||||
option(FREECAD_USE_FREETYPE "Builds the features using FreeType libs" ON)
|
||||
option(FREECAD_BUILD_DEBIAN "Prepare for a build of a Debian package" OFF)
|
||||
option(FREECAD_CHECK_PIVY "Check for pivy version using Python at build time" ON)
|
||||
@@ -120,6 +121,7 @@ macro(InitializeFreeCADBuildOptions)
|
||||
option(BUILD_INSPECTION "Build the FreeCAD inspection module" ON)
|
||||
option(BUILD_JTREADER "Build the FreeCAD jt reader module" OFF)
|
||||
option(BUILD_MATERIAL "Build the FreeCAD material module" ON)
|
||||
option(BUILD_MATERIAL_EXTERNAL "Build the FreeCAD material external interface module" OFF)
|
||||
option(BUILD_MESH "Build the FreeCAD mesh module" ON)
|
||||
option(BUILD_MESH_PART "Build the FreeCAD mesh part module" ON)
|
||||
option(BUILD_FLAT_MESH "Build the FreeCAD flat mesh module" ON)
|
||||
|
||||
@@ -104,6 +104,7 @@ macro(PrintFinalReport)
|
||||
value(BUILD_INSPECTION)
|
||||
value(BUILD_JTREADER)
|
||||
value(BUILD_MATERIAL)
|
||||
value(BUILD_MATERIAL_EXTERNAL)
|
||||
value(BUILD_MESH)
|
||||
value(BUILD_MESH_PART)
|
||||
value(BUILD_OPENSCAD)
|
||||
|
||||
@@ -19,18 +19,29 @@ macro(SetGlobalCompilerAndLinkerSettings)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mxgot")
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
|
||||
# Only add -Og if no -O* optimization flag exists
|
||||
if (NOT "${CMAKE_C_FLAGS_DEBUG}" MATCHES "-O[a-z0-9]+")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Og")
|
||||
endif()
|
||||
if (NOT "${CMAKE_CXX_FLAGS_DEBUG}" MATCHES "-O[a-z0-9]+")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og")
|
||||
endif()
|
||||
endif()
|
||||
if(MSVC)
|
||||
# set default compiler settings
|
||||
add_definitions(-D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR -DNOMINMAX)
|
||||
add_compile_options(/Zm150 /bigobj)
|
||||
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DFC_DEBUG")
|
||||
# set default libs
|
||||
set (CMAKE_C_STANDARD_LIBRARIES "kernel32.lib user32.lib gdi32.lib winspool.lib SHFolder.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib winmm.lib comsupp.lib Ws2_32.lib dbghelp.lib ")
|
||||
set (CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES}")
|
||||
# set linker flag /nodefaultlib
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NODEFAULTLIB")
|
||||
set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /NODEFAULTLIB")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB")
|
||||
if (MSVC_VERSION LESS 1930) # Anything before VS 2022
|
||||
# set default libs
|
||||
set (CMAKE_C_STANDARD_LIBRARIES "kernel32.lib user32.lib gdi32.lib winspool.lib SHFolder.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib winmm.lib comsupp.lib Ws2_32.lib dbghelp.lib ")
|
||||
set (CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES}")
|
||||
# set linker flag /nodefaultlib
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NODEFAULTLIB")
|
||||
set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /NODEFAULTLIB")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB")
|
||||
endif()
|
||||
if(FREECAD_RELEASE_PDB)
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
|
||||
set (CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG")
|
||||
|
||||
@@ -34,8 +34,8 @@ macro(SetupLibFmt)
|
||||
cmake_policy(SET CMP0135 NEW)
|
||||
endif()
|
||||
FetchContent_Declare(fmt
|
||||
URL https://github.com/fmtlib/fmt/archive/refs/tags/9.1.0.zip
|
||||
URL_MD5 e6754011ff56bfc37631fcc90961e377
|
||||
URL https://github.com/fmtlib/fmt/archive/refs/tags/11.1.4.zip
|
||||
URL_MD5 90667b07f34d91554cf8285ae234ff66
|
||||
)
|
||||
FetchContent_MakeAvailable(fmt)
|
||||
set_target_properties(fmt PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
@@ -27,6 +27,12 @@ endif()
|
||||
find_package(XercesC REQUIRED PATHS ${FREECAD_LIBPACK_DIR}/cmake NO_DEFAULT_PATH)
|
||||
message(STATUS "Found LibPack 3 XercesC ${XercesC_VERSION}")
|
||||
|
||||
if(FREECAD_LIBPACK_VERSION VERSION_GREATER_EQUAL "3.1.1")
|
||||
set(FREECAD_USE_EXTERNAL_E57FORMAT ON)
|
||||
find_package(E57Format REQUIRED PATHS ${FREECAD_LIBPACK_DIR}/lib/cmake/e57format NO_DEFAULT_PATH)
|
||||
message(STATUS "Found LibPack 3 e57format ${e57format_VERSION}")
|
||||
endif()
|
||||
|
||||
find_package(yaml-cpp REQUIRED PATHS ${FREECAD_LIBPACK_DIR}/lib/cmake NO_DEFAULT_PATH)
|
||||
message(STATUS "Found LibPack 3 yaml-cpp ${yaml-cpp_VERSION}")
|
||||
|
||||
|
||||
37
package/rattler-build/build.bat
Normal file
37
package/rattler-build/build.bat
Normal file
@@ -0,0 +1,37 @@
|
||||
@echo on
|
||||
|
||||
@REM :: free up extra disk space, compare
|
||||
@REM :: https://github.com/conda-forge/conda-smithy/issues/1949
|
||||
@REM rmdir /s /q C:\hostedtoolcache\windows
|
||||
|
||||
@REM set "CFLAGS= "
|
||||
@REM set "CXXFLAGS= -DBOOST_PROGRAM_OPTIONS_DYN_LINK=1"
|
||||
@REM set "LDFLAGS_SHARED= ucrt.lib"
|
||||
|
||||
set "CMAKE_GENERATOR="
|
||||
set "CMAKE_GENERATOR_PLATFORM="
|
||||
|
||||
cmake ^
|
||||
--preset conda-windows-release ^
|
||||
-D CMAKE_INCLUDE_PATH:FILEPATH="%LIBRARY_PREFIX%/include" ^
|
||||
-D CMAKE_INSTALL_LIBDIR:FILEPATH="%LIBRARY_PREFIX%/lib" ^
|
||||
-D CMAKE_INSTALL_PREFIX:FILEPATH="%LIBRARY_PREFIX%" ^
|
||||
-D CMAKE_LIBRARY_PATH:FILEPATH="%LIBRARY_PREFIX%/lib" ^
|
||||
-D CMAKE_PREFIX_PATH:FILEPATH="%LIBRARY_PREFIX%" ^
|
||||
-D FREECAD_USE_OCC_VARIANT="Official Version" ^
|
||||
-D INSTALL_TO_SITEPACKAGES:BOOL=ON ^
|
||||
-D OCC_INCLUDE_DIR:FILEPATH="%LIBRARY_PREFIX%/include" ^
|
||||
-D OCCT_CMAKE_FALLBACK:BOOL=OFF ^
|
||||
-D Python_EXECUTABLE:FILEPATH="%PYTHON%" ^
|
||||
-D Python3_EXECUTABLE:FILEPATH="%PYTHON%" ^
|
||||
-B build ^
|
||||
-S . ^
|
||||
${CMAKE_PLATFORM_FLAGS[@]}
|
||||
if %ERRORLEVEL% neq 0 exit 1
|
||||
|
||||
ninja -C build install
|
||||
if %ERRORLEVEL% neq 0 exit 1
|
||||
|
||||
rmdir /s /q "%LIBRARY_PREFIX%\doc"
|
||||
ren %LIBRARY_PREFIX%\bin\FreeCAD.exe freecad.exe
|
||||
ren %LIBRARY_PREFIX%\bin\FreeCADCmd.exe freecadcmd.exe
|
||||
47
package/rattler-build/build.sh
Normal file
47
package/rattler-build/build.sh
Normal file
@@ -0,0 +1,47 @@
|
||||
if [[ ${HOST} =~ .*linux.* ]]; then
|
||||
CMAKE_PRESET=conda-linux-release
|
||||
fi
|
||||
|
||||
if [[ ${HOST} =~ .*darwin.* ]]; then
|
||||
CMAKE_PRESET=conda-macos-release
|
||||
|
||||
# add hacks for osx here!
|
||||
echo "adding hacks for osx"
|
||||
|
||||
# install space-mouse
|
||||
/usr/bin/curl -o /tmp/3dFW.dmg -L 'https://download.3dconnexion.com/drivers/mac/10-7-0_B564CC6A-6E81-42b0-82EC-418EA823B81A/3DxWareMac_v10-7-0_r3411.dmg'
|
||||
hdiutil attach -readonly /tmp/3dFW.dmg
|
||||
sudo installer -package /Volumes/3Dconnexion\ Software/Install\ 3Dconnexion\ software.pkg -target /
|
||||
diskutil eject /Volumes/3Dconnexion\ Software
|
||||
CMAKE_PLATFORM_FLAGS+=(-DFREECAD_USE_3DCONNEXION:BOOL=ON)
|
||||
CMAKE_PLATFORM_FLAGS+=(-D3DCONNEXIONCLIENT_FRAMEWORK:FILEPATH="/Library/Frameworks/3DconnexionClient.framework")
|
||||
|
||||
CXXFLAGS="${CXXFLAGS} -D_LIBCPP_DISABLE_AVAILABILITY"
|
||||
fi
|
||||
|
||||
unset CMAKE_GENERATOR
|
||||
unset CMAKE_GENERATOR_PLATFORM
|
||||
|
||||
cmake \
|
||||
--preset ${CMAKE_PRESET} \
|
||||
-D CMAKE_IGNORE_PREFIX_PATH="/opt/homebrew;/usr/local/homebrew" \
|
||||
-D CMAKE_INCLUDE_PATH:FILEPATH="$PREFIX/include" \
|
||||
-D CMAKE_INSTALL_LIBDIR:FILEPATH="$PREFIX/lib" \
|
||||
-D CMAKE_INSTALL_PREFIX:FILEPATH="$PREFIX" \
|
||||
-D CMAKE_LIBRARY_PATH:FILEPATH="$PREFIX/lib" \
|
||||
-D CMAKE_PREFIX_PATH:FILEPATH="$PREFIX" \
|
||||
-D FREECAD_USE_OCC_VARIANT="Official Version" \
|
||||
-D INSTALL_TO_SITEPACKAGES:BOOL=ON \
|
||||
-D OCC_INCLUDE_DIR:FILEPATH="$PREFIX/include" \
|
||||
-D OCCT_CMAKE_FALLBACK:BOOL=OFF \
|
||||
-D Python_EXECUTABLE:FILEPATH="$PYTHON" \
|
||||
-D Python3_EXECUTABLE:FILEPATH="$PYTHON" \
|
||||
-B build \
|
||||
-S . \
|
||||
${CMAKE_PLATFORM_FLAGS[@]}
|
||||
|
||||
cmake --build build
|
||||
cmake --install build
|
||||
|
||||
mv ${PREFIX}/bin/FreeCAD ${PREFIX}/bin/freecad || true
|
||||
mv ${PREFIX}/bin/FreeCADCmd ${PREFIX}/bin/freecadcmd || true
|
||||
7
package/rattler-build/conda_build_config.yaml
Normal file
7
package/rattler-build/conda_build_config.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
c_compiler: # [win]
|
||||
- vs2022 # [win]
|
||||
cxx_compiler: # [win]
|
||||
- vs2022 # [win]
|
||||
|
||||
MACOSX_SDK_VERSION: # [osx]
|
||||
- '11.0' # [osx]
|
||||
31
package/rattler-build/linux/AppDir/AppRun
Executable file
31
package/rattler-build/linux/AppDir/AppRun
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
HERE="$(dirname "$(readlink -f "${0}")")"
|
||||
export PREFIX=${HERE}/usr
|
||||
# export LD_LIBRARY_PATH=${HERE}/usr/lib${LD_LIBRARY_PATH:+':'}$LD_LIBRARY_PATH
|
||||
export PYTHONHOME=${HERE}/usr
|
||||
export PATH_TO_FREECAD_LIBDIR=${HERE}/usr/lib
|
||||
# export QT_QPA_PLATFORM_PLUGIN_PATH=${HERE}/usr/plugins
|
||||
# export QT_XKB_CONFIG_ROOT=${HERE}/usr/lib
|
||||
export FONTCONFIG_FILE=/etc/fonts/fonts.conf
|
||||
export FONTCONFIG_PATH=/etc/fonts
|
||||
|
||||
# Show packages info if DEBUG env variable is set
|
||||
if [ "$DEBUG" = 1 ]; then
|
||||
cat ${HERE}/packages.txt
|
||||
fi
|
||||
|
||||
# SSL
|
||||
# https://forum.freecad.org/viewtopic.php?f=4&t=34873&start=20#p327416
|
||||
export SSL_CERT_FILE=$PREFIX/ssl/cacert.pem
|
||||
# https://github.com/FreeCAD/FreeCAD-AppImage/pull/20
|
||||
export GIT_SSL_CAINFO=$HERE/usr/ssl/cacert.pem
|
||||
|
||||
# Support for launching other applications (from /usr/bin)
|
||||
# https://github.com/FreeCAD/FreeCAD-AppImage/issues/30
|
||||
if [ ! -z "$1" ] && [ -e "$HERE/usr/bin/$1" ] ; then
|
||||
MAIN="$HERE/usr/bin/$1" ; shift
|
||||
else
|
||||
MAIN="$HERE/usr/bin/freecad"
|
||||
fi
|
||||
|
||||
"${MAIN}" "$@"
|
||||
84
package/rattler-build/linux/create_bundle.sh
Executable file
84
package/rattler-build/linux/create_bundle.sh
Executable file
@@ -0,0 +1,84 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
conda_env="AppDir/usr"
|
||||
|
||||
mkdir -p ${conda_env}
|
||||
|
||||
cp -a ../.pixi/envs/default/* ${conda_env}
|
||||
|
||||
export PATH="${PWD}/${conda_env}/bin:${PATH}"
|
||||
export CONDA_PREFIX="${PWD}/${conda_env}"
|
||||
|
||||
echo -e "\nDelete unnecessary stuff"
|
||||
rm -rf ${conda_env}/include
|
||||
find ${conda_env} -name \*.a -delete
|
||||
|
||||
mv ${conda_env}/bin ${conda_env}/bin_tmp
|
||||
mkdir ${conda_env}/bin
|
||||
cp ${conda_env}/bin_tmp/freecad ${conda_env}/bin/
|
||||
cp ${conda_env}/bin_tmp/freecadcmd ${conda_env}/bin
|
||||
cp ${conda_env}/bin_tmp/ccx ${conda_env}/bin/
|
||||
cp ${conda_env}/bin_tmp/python ${conda_env}/bin/
|
||||
cp ${conda_env}/bin_tmp/pip ${conda_env}/bin/
|
||||
cp ${conda_env}/bin_tmp/pyside6-rcc ${conda_env}/bin/
|
||||
cp ${conda_env}/bin_tmp/gmsh ${conda_env}/bin/
|
||||
cp ${conda_env}/bin_tmp/dot ${conda_env}/bin/
|
||||
cp ${conda_env}/bin_tmp/unflatten ${conda_env}/bin/
|
||||
rm -rf ${conda_env}/bin_tmp
|
||||
|
||||
sed -i '1s|.*|#!/usr/bin/env python|' ${conda_env}/bin/pip
|
||||
|
||||
echo -e "\nCopying Icon and Desktop file"
|
||||
cp ${conda_env}/share/applications/org.freecad.FreeCAD.desktop AppDir/
|
||||
sed -i 's/Exec=FreeCAD/Exec=AppRun/g' AppDir/org.freecad.FreeCAD.desktop
|
||||
cp ${conda_env}/share/icons/hicolor/scalable/apps/org.freecad.FreeCAD.svg AppDir/
|
||||
|
||||
# Remove __pycache__ folders and .pyc files
|
||||
find . -path "*/__pycache__/*" -delete
|
||||
find . -name "*.pyc" -type f -delete
|
||||
|
||||
# reduce size
|
||||
rm -rf ${conda_env}/conda-meta/
|
||||
rm -rf ${conda_env}/doc/global/
|
||||
rm -rf ${conda_env}/share/gtk-doc/
|
||||
rm -rf ${conda_env}/lib/cmake/
|
||||
|
||||
find . -name "*.h" -type f -delete
|
||||
find . -name "*.cmake" -type f -delete
|
||||
|
||||
python_version=$(python -c 'import platform; print("py" + platform.python_version_tuple()[0] + platform.python_version_tuple()[1])')
|
||||
version_name="FreeCAD_${BUILD_TAG}-Linux-$(uname -m)-${python_version}"
|
||||
|
||||
echo -e "\################"
|
||||
echo -e "version_name: ${version_name}"
|
||||
echo -e "################"
|
||||
|
||||
pixi list -e default > AppDir/packages.txt
|
||||
sed -i "1s/.*/\nLIST OF PACKAGES:/" AppDir/packages.txt
|
||||
|
||||
export tag="weekly-builds" # should retrieve from git tag
|
||||
|
||||
curl -LO https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-$(uname -m).AppImage
|
||||
chmod a+x appimagetool-$(uname -m).AppImage
|
||||
|
||||
echo -e "\nCreate the appimage"
|
||||
# export GPG_TTY=$(tty)
|
||||
chmod a+x ./AppDir/AppRun
|
||||
./appimagetool-$(uname -m).AppImage \
|
||||
--comp zstd \
|
||||
--mksquashfs-opt -Xcompression-level \
|
||||
--mksquashfs-opt 22 \
|
||||
-u "gh-releases-zsync|FreeCAD|FreeCAD-Bundle|$tag|FreeCAD*$(uname -m)*.AppImage.zsync" \
|
||||
AppDir ${version_name}.AppImage
|
||||
# -s --sign-key ${GPG_KEY_ID} \
|
||||
|
||||
echo -e "\nCreate hash"
|
||||
sha256sum ${version_name}.AppImage > ${version_name}.AppImage-SHA256.txt
|
||||
|
||||
if [ "${UPLOAD_RELEASE}" == "true" ]; then
|
||||
gh release create ${BUILD_TAG} --title "Weekly Build ${BUILD_TAG}" --notes "Weekly Build ${BUILD_TAG}" --prerelease || true
|
||||
gh release upload --clobber ${BUILD_TAG} "${version_name}.AppImage" "${version_name}.AppImage-SHA256.txt"
|
||||
fi
|
||||
90
package/rattler-build/osx/Info.plist.template
Normal file
90
package/rattler-build/osx/Info.plist.template
Normal file
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>FreeCAD</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string></string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>freecad.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.freecad.FreeCAD</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
<string></string>
|
||||
<key>CFBundleName</key>
|
||||
<string>APPLICATION_MENU_NAME</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string></string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>FREECAD_VERSION</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string></string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<string>True</string>
|
||||
<key>NSRequiresAquaSystemAppearance</key>
|
||||
<string>False</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>FCStd</string>
|
||||
<string>FCMat</string>
|
||||
<string>FCParam</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>freecad-doc.icns</string>
|
||||
<key>LSIsAppleDefaultForType</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>FCMacro</string>
|
||||
<string>FCScript</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>freecad-script.icns</string>
|
||||
<key>LSIsAppleDefaultForType</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>FreeCAD Document</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.freecad.fcstd</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>FCStd</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
85
package/rattler-build/osx/create_bundle.sh
Normal file
85
package/rattler-build/osx/create_bundle.sh
Normal file
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
conda_env="FreeCAD.app/Contents/Resources"
|
||||
|
||||
mkdir -p ${conda_env}
|
||||
|
||||
cp -a ../.pixi/envs/default/* ${conda_env}
|
||||
|
||||
export PATH="${PWD}/${conda_env}/bin:${PATH}"
|
||||
export CONDA_PREFIX="${PWD}/${conda_env}"
|
||||
|
||||
# delete unnecessary stuff
|
||||
rm -rf ${conda_env}/include
|
||||
find ${conda_env} -name \*.a -delete
|
||||
|
||||
mv ${conda_env}/bin ${conda_env}/bin_tmp
|
||||
mkdir ${conda_env}/bin
|
||||
cp ${conda_env}/bin_tmp/freecad ${conda_env}/bin/
|
||||
cp ${conda_env}/bin_tmp/freecadcmd ${conda_env}/bin
|
||||
cp ${conda_env}/bin_tmp/ccx ${conda_env}/bin/
|
||||
cp ${conda_env}/bin_tmp/python ${conda_env}/bin/
|
||||
cp ${conda_env}/bin_tmp/pip ${conda_env}/bin/
|
||||
cp ${conda_env}/bin_tmp/pyside6-rcc ${conda_env}/bin/
|
||||
cp ${conda_env}/bin_tmp/gmsh ${conda_env}/bin/
|
||||
cp ${conda_env}/bin_tmp/dot ${conda_env}/bin/
|
||||
cp ${conda_env}/bin_tmp/unflatten ${conda_env}/bin/
|
||||
rm -rf ${conda_env}/bin_tmp
|
||||
|
||||
sed -i '1s|.*|#!/usr/bin/env python|' ${conda_env}/bin/pip
|
||||
|
||||
# copy resources
|
||||
cp resources/* ${conda_env}
|
||||
|
||||
# Remove __pycache__ folders and .pyc files
|
||||
find . -path "*/__pycache__/*" -delete
|
||||
find . -name "*.pyc" -type f -delete
|
||||
|
||||
# fix problematic rpaths and reexport_dylibs for signing
|
||||
# see https://github.com/FreeCAD/FreeCAD/issues/10144#issuecomment-1836686775
|
||||
# and https://github.com/FreeCAD/FreeCAD-Bundle/pull/203
|
||||
python ../scripts/fix_macos_lib_paths.py ${conda_env}/lib
|
||||
|
||||
# build and install the launcher
|
||||
cmake -B build launcher
|
||||
cmake --build build
|
||||
mkdir -p FreeCAD.app/Contents/MacOS
|
||||
cp build/FreeCAD FreeCAD.app/Contents/MacOS/FreeCAD
|
||||
|
||||
python_version=$(python -c 'import platform; print("py" + platform.python_version_tuple()[0] + platform.python_version_tuple()[1])')
|
||||
version_name="FreeCAD_${BUILD_TAG}-macOS-$(uname -m)-${python_version}"
|
||||
application_menu_name="FreeCAD_${BUILD_TAG}"
|
||||
|
||||
echo -e "\################"
|
||||
echo -e "version_name: ${version_name}"
|
||||
echo -e "################"
|
||||
|
||||
cp Info.plist.template ${conda_env}/../Info.plist
|
||||
sed -i "s/FREECAD_VERSION/${version_name}/" ${conda_env}/../Info.plist
|
||||
sed -i "s/APPLICATION_MENU_NAME/${application_menu_name}/" ${conda_env}/../Info.plist
|
||||
|
||||
pixi list -e default > FreeCAD.app/Contents/packages.txt
|
||||
sed -i '1s/.*/\nLIST OF PACKAGES:/' FreeCAD.app/Contents/packages.txt
|
||||
|
||||
# copy the plugin into its final location
|
||||
cp -a ${conda_env}/Library ${conda_env}/..
|
||||
rm -rf ${conda_env}/Library
|
||||
|
||||
if [[ "${SIGN_RELEASE}" == "true" ]]; then
|
||||
# create the signed dmg
|
||||
./macos_sign_and_notarize.zsh -p "FreeCAD" -k ${SIGNING_KEY_ID} -o "${version_name}.dmg"
|
||||
else
|
||||
# create the dmg
|
||||
dmgbuild -s dmg_settings.py "FreeCAD" "${version_name}.dmg"
|
||||
fi
|
||||
|
||||
# create hash
|
||||
sha256sum ${version_name}.dmg > ${version_name}.dmg-SHA256.txt
|
||||
|
||||
if [[ "${UPLOAD_RELEASE}" == "true" ]]; then
|
||||
gh release create ${BUILD_TAG} --title "Weekly Build ${BUILD_TAG}" --notes "Weekly Build ${BUILD_TAG}" --prerelease || true
|
||||
gh release upload --clobber ${BUILD_TAG} "${version_name}.dmg" "${version_name}.dmg-SHA256.txt"
|
||||
fi
|
||||
12
package/rattler-build/osx/dmg_settings.py
Normal file
12
package/rattler-build/osx/dmg_settings.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# Ensure default values are set in defines if they are not already provided
|
||||
defines.setdefault('containing_folder', '.')
|
||||
defines.setdefault('app_name', 'FreeCAD.app')
|
||||
defines.setdefault('icon_path', 'Contents/Resources/freecad.icns')
|
||||
|
||||
|
||||
files = [f"{defines['containing_folder']}/{defines['app_name']}"]
|
||||
symlinks = {"Applications": "/Applications"}
|
||||
badge_icon = f"{defines['containing_folder']}/{defines['app_name']}/{defines['icon_path']}"
|
||||
window_rect = ((200, 200), (600, 400))
|
||||
icon_locations = {f"{defines['app_name']}": (180, 150), "Applications": (420, 150)}
|
||||
size = "4g"
|
||||
8
package/rattler-build/osx/entitlements.plist
Normal file
8
package/rattler-build/osx/entitlements.plist
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
8
package/rattler-build/osx/launcher/CMakeLists.txt
Normal file
8
package/rattler-build/osx/launcher/CMakeLists.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(freecad-launcher LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "Minimum OS X deployment version" FORCE)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
add_executable(FreeCAD FreeCAD.cpp)
|
||||
target_link_libraries(FreeCAD)
|
||||
75
package/rattler-build/osx/launcher/FreeCAD.cpp
Normal file
75
package/rattler-build/osx/launcher/FreeCAD.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <libgen.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char *argv[], char *const *envp) {
|
||||
char *cwd = dirname(realpath(argv[0], NULL));
|
||||
|
||||
std::string FreeCAD = realpath((std::string(cwd) + "/../Resources/bin/freecad").c_str(), NULL);
|
||||
|
||||
std::map<std::string, std::string> env;
|
||||
for(int i = 0; envp[i] != NULL; ++i) {
|
||||
std::string e(envp[i]);
|
||||
auto sep = e.find('=');
|
||||
auto var = e.substr(0, sep);
|
||||
auto value = e.substr(sep+1, std::string::npos);
|
||||
env[var] = value;
|
||||
}
|
||||
|
||||
std::string prefix = realpath((std::string(cwd) + "/../Resources").c_str(), NULL);
|
||||
env["PREFIX"] = prefix;
|
||||
env["LD_LIBRARY_PATH"] = prefix + "/lib";
|
||||
env["PYTHONPATH"] = prefix;
|
||||
env["PYTHONHOME"] = prefix;
|
||||
env["FONTCONFIG_FILE"] = "/etc/fonts/fonts.conf";
|
||||
env["FONTCONFIG_PATH"] = "/etc/fonts";
|
||||
env["LANG"] = "UTF-8"; // https://forum.freecad.org/viewtopic.php?f=22&t=42644
|
||||
env["SSL_CERT_FILE"] = prefix + "/ssl/cacert.pem"; // https://forum.freecad.org/viewtopic.php?f=3&t=42825
|
||||
env["GIT_SSL_CAINFO"] = prefix + "/ssl/cacert.pem";
|
||||
env["QT_MAC_WANTS_LAYER"] = "1";
|
||||
|
||||
char **new_env = new char*[env.size() + 1];
|
||||
int i = 0;
|
||||
for (const auto& [var, value] : env) {
|
||||
auto line = var + '=' + value;
|
||||
size_t len = line.length() + 1;
|
||||
new_env[i] = new char[len];
|
||||
memset(new_env[i], 0, len);
|
||||
strncpy(new_env[i], line.c_str(), len);
|
||||
i++;
|
||||
}
|
||||
new_env[i] = NULL;
|
||||
|
||||
i = 0;
|
||||
while(new_env[i] != NULL) {
|
||||
std::cout << new_env[i] << std::endl;
|
||||
i++;
|
||||
}
|
||||
|
||||
std::cout << "Running: " << FreeCAD << std::endl;
|
||||
i = 0;
|
||||
while(argv[i] != NULL) {
|
||||
i++;
|
||||
}
|
||||
|
||||
char **new_argv = new char*[i + 1];
|
||||
new_argv[0] = new char[FreeCAD.length() + 1];
|
||||
memset(new_argv[0], 0, FreeCAD.length() + 1);
|
||||
strncpy(new_argv[0], FreeCAD.c_str(), FreeCAD.length());
|
||||
|
||||
i = 1;
|
||||
while(argv[i] != NULL) {
|
||||
new_argv[i] = new char[strlen(argv[i])+1];
|
||||
memset(new_argv[i], 0, strlen(argv[i])+1);
|
||||
strncpy(new_argv[i], argv[i], strlen(argv[i]));
|
||||
i++;
|
||||
}
|
||||
new_argv[i] = NULL;
|
||||
|
||||
return execve(FreeCAD.c_str(), new_argv, new_env);
|
||||
}
|
||||
126
package/rattler-build/osx/macos_sign_and_notarize.zsh
Executable file
126
package/rattler-build/osx/macos_sign_and_notarize.zsh
Executable file
@@ -0,0 +1,126 @@
|
||||
#!/bin/zsh
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
# Default values
|
||||
SIGNING_KEY_ID="${FREECAD_SIGNING_KEY_ID}"
|
||||
KEYCHAIN_PROFILE="FreeCAD"
|
||||
CONTAINING_FOLDER="."
|
||||
APP_NAME="FreeCAD.app"
|
||||
VOLUME_NAME="FreeCAD"
|
||||
DMG_NAME="FreeCAD-macOS-$(uname -m).dmg"
|
||||
DMG_SETTINGS="dmg_settings.py"
|
||||
|
||||
# Function to display usage information
|
||||
function usage {
|
||||
echo "Usage: $0 [-k|--key-id <signing_key_id>] [-p|--keychain-profile <keychain_profile>]"
|
||||
echo " [-d|--dir <containing_folder>] [-n|--app-name <app_name.app>]"
|
||||
echo " [-v|--volume-name <volume_name>] [-o|--output <image_name.dmg>]"
|
||||
echo " [-s|--dmg-settings <dmg_settings.py>]"
|
||||
echo
|
||||
echo "This script signs and notarizes a FreeCAD.app bundle. It expects that the bundle is in a folder"
|
||||
echo "by itself (that folder will be used as the basis for the created disk image file, so anything"
|
||||
echo "else in it will become part of the image). That folder should be located in the same folder as"
|
||||
echo "this script."
|
||||
echo
|
||||
echo "If <signing_key_id> is not passed it defaults to env variable FREECAD_SIGNING_KEY_ID, it should"
|
||||
echo "be a Developer ID Application certificate that has been installed into the login keychain."
|
||||
echo "For a list of available keys see the output of"
|
||||
echo " security find-identity -p basic -v"
|
||||
echo "For instructions on how to configure the credentials for the tool for use before running this"
|
||||
echo "script see the documentation for"
|
||||
echo " xcrun notarytool store-credentials"
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case $1 in
|
||||
-k|--key-id)
|
||||
SIGNING_KEY_ID="$2"
|
||||
shift 2
|
||||
;;
|
||||
-p|--keychain-profile)
|
||||
KEYCHAIN_PROFILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-d|--dir)
|
||||
CONTAINING_FOLDER="$2"
|
||||
shift 2
|
||||
;;
|
||||
-n|--app-name)
|
||||
APP_NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
-v|--volume-name)
|
||||
VOLUME_NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
-o|--output)
|
||||
DMG_NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
-s|--dmg-settings)
|
||||
DMG_SETTINGS="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
echo "Unknown parameter passed: $1"
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check if SIGNING_KEY_ID is set
|
||||
if [ -z "$SIGNING_KEY_ID" ]; then
|
||||
echo "Error: Signing key ID is required."
|
||||
usage
|
||||
fi
|
||||
|
||||
# Check for dmgbuild executable
|
||||
if ! command -v dmgbuild &> /dev/null; then
|
||||
echo "Error: dmgbuild not installed. Please install it for example using pip:"
|
||||
echo 'pip3 install "dmgbuild[badge_icons]>=1.6.0,<1.7.0"'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function run_codesign {
|
||||
echo "Signing $1"
|
||||
/usr/bin/codesign --options runtime -f -s ${SIGNING_KEY_ID} --timestamp --entitlements entitlements.plist "$1"
|
||||
}
|
||||
|
||||
IFS=$'\n'
|
||||
dylibs=($(/usr/bin/find "${CONTAINING_FOLDER}/${APP_NAME}" -name "*.dylib"))
|
||||
shared_objects=($(/usr/bin/find "${CONTAINING_FOLDER}/${APP_NAME}" -name "*.so"))
|
||||
bundles=($(/usr/bin/find "${CONTAINING_FOLDER}/${APP_NAME}" -name "*.bundle"))
|
||||
executables=($(/usr/bin/find "${CONTAINING_FOLDER}/${APP_NAME}" -type f -perm +111 -exec file {} + | grep "Mach-O 64-bit executable" | sed 's/:.*//g'))
|
||||
IFS=$' \t\n' # The default
|
||||
|
||||
signed_files=("${dylibs[@]}" "${shared_objects[@]}" "${bundles[@]}" "${executables[@]}")
|
||||
|
||||
# This list of files is generated from:
|
||||
# file `find . -type f -perm +111 -print` | grep "Mach-O 64-bit executable" | sed 's/:.*//g'
|
||||
for exe in ${signed_files}; do
|
||||
run_codesign "${exe}"
|
||||
done
|
||||
|
||||
# Two additional files that must be signed that aren't caught by the above searches:
|
||||
run_codesign "${CONTAINING_FOLDER}/${APP_NAME}/Contents/packages.txt"
|
||||
run_codesign "${CONTAINING_FOLDER}/${APP_NAME}/Contents/Library/QuickLook/QuicklookFCStd.qlgenerator/Contents/MacOS/QuicklookFCStd"
|
||||
|
||||
# Finally, sign the app itself (must be done last)
|
||||
run_codesign "${CONTAINING_FOLDER}/${APP_NAME}"
|
||||
|
||||
# Create a disk image from the folder
|
||||
echo "Creating disk image ${DMG_NAME}"
|
||||
dmgbuild -s ${DMG_SETTINGS} -Dcontaining_folder="${CONTAINING_FOLDER}" -Dapp_name="${APP_NAME}" "${VOLUME_NAME}" "${DMG_NAME}"
|
||||
|
||||
# Submit it for notarization (requires that an App Store API Key has been set up in the notarytool)
|
||||
time xcrun notarytool submit --wait --keychain-profile "${KEYCHAIN_PROFILE}" "${DMG_NAME}"
|
||||
|
||||
# Assuming that notarization succeeded, it's a good practice to staple that notarization to the DMG
|
||||
xcrun stapler staple "${DMG_NAME}"
|
||||
BIN
package/rattler-build/osx/resources/freecad-doc.icns
Normal file
BIN
package/rattler-build/osx/resources/freecad-doc.icns
Normal file
Binary file not shown.
BIN
package/rattler-build/osx/resources/freecad-script.icns
Normal file
BIN
package/rattler-build/osx/resources/freecad-script.icns
Normal file
Binary file not shown.
BIN
package/rattler-build/osx/resources/freecad.icns
Normal file
BIN
package/rattler-build/osx/resources/freecad.icns
Normal file
Binary file not shown.
17927
package/rattler-build/pixi.lock
Normal file
17927
package/rattler-build/pixi.lock
Normal file
File diff suppressed because it is too large
Load Diff
66
package/rattler-build/pixi.toml
Normal file
66
package/rattler-build/pixi.toml
Normal file
@@ -0,0 +1,66 @@
|
||||
[workspace]
|
||||
channels = [
|
||||
"https://prefix.dev/pixi-build-backends",
|
||||
"https://prefix.dev/conda-forge",
|
||||
]
|
||||
platforms = ["linux-64", "linux-aarch64", "osx-64", "osx-arm64", "win-64"]
|
||||
preview = ["pixi-build"]
|
||||
|
||||
[package]
|
||||
name = "freecad"
|
||||
version = "1.1.0dev"
|
||||
homepage = "https://freecad.org"
|
||||
repository = "https://github.com/FreeCAD/FreeCAD"
|
||||
description = "FreeCAD"
|
||||
|
||||
[package.build]
|
||||
backend = { name = "pixi-build-rattler-build", version = "*" }
|
||||
|
||||
[feature.freecad.dependencies]
|
||||
freecad = { path = "." }
|
||||
|
||||
[feature.package.dependencies]
|
||||
python = ">=3.11,<3.12"
|
||||
|
||||
## Linux (x86-64)
|
||||
[feature.package.target.linux-64.dependencies]
|
||||
coreutils = "*"
|
||||
|
||||
[feature.package.target.linux-64.tasks]
|
||||
create_bundle = 'bash -c "cd linux && bash create_bundle.sh"'
|
||||
|
||||
## Linux (aarch64)
|
||||
[feature.package.target.linux-aarch64.dependencies]
|
||||
coreutils = "*"
|
||||
|
||||
[feature.package.target.linux-aarch64.tasks]
|
||||
create_bundle = 'bash -c "cd linux && bash create_bundle.sh"'
|
||||
|
||||
## macOS (Intel)
|
||||
[feature.package.target.osx-64.dependencies]
|
||||
coreutils = "*"
|
||||
dmgbuild = "*"
|
||||
sed = "*"
|
||||
|
||||
[feature.package.target.osx-64.tasks]
|
||||
create_bundle = 'bash -c "cd osx && bash create_bundle.sh"'
|
||||
|
||||
## macOS (Apple Silicon)
|
||||
[feature.package.target.osx-arm64.dependencies]
|
||||
coreutils = "*"
|
||||
dmgbuild = "*"
|
||||
sed = "*"
|
||||
|
||||
[feature.package.target.osx-arm64.tasks]
|
||||
create_bundle = 'bash -c "cd osx && bash create_bundle.sh"'
|
||||
|
||||
## Windows dependencies (x86-64)
|
||||
[feature.package.target.win-64.dependencies]
|
||||
git = "*"
|
||||
|
||||
[feature.package.target.win-64.tasks]
|
||||
create_bundle = 'bash -c "cd windows && bash create_bundle.sh"'
|
||||
|
||||
[environments]
|
||||
default = ["freecad"]
|
||||
package = ["package"]
|
||||
176
package/rattler-build/recipe.yaml
Normal file
176
package/rattler-build/recipe.yaml
Normal file
@@ -0,0 +1,176 @@
|
||||
context:
|
||||
version: "1.1.0dev"
|
||||
|
||||
package:
|
||||
name: freecad
|
||||
version: "${{ version }}"
|
||||
|
||||
source:
|
||||
path: ../..
|
||||
use_gitignore: true
|
||||
|
||||
build:
|
||||
number: 0
|
||||
|
||||
requirements:
|
||||
build:
|
||||
- ccache
|
||||
- cmake
|
||||
- compilers
|
||||
- doxygen
|
||||
- ninja
|
||||
- noqt5
|
||||
- python>=3.11,<3.12
|
||||
- qt6-main<6.9
|
||||
- swig
|
||||
|
||||
- if: linux and x86_64
|
||||
then:
|
||||
- clang
|
||||
- clangxx
|
||||
- kernel-headers_linux-64
|
||||
- libdrm-cos7-x86_64
|
||||
- libselinux-cos7-x86_64
|
||||
- libsepol-cos7-x86_64
|
||||
- libspnav
|
||||
- libx11-common-cos7-x86_64
|
||||
- libx11-cos7-x86_64
|
||||
- libxau-cos7-x86_64
|
||||
- libxcb-cos7-x86_64
|
||||
- libxdamage-cos7-x86_64
|
||||
- libxext-cos7-x86_64
|
||||
- libxfixes-cos7-x86_64
|
||||
- libxi-cos7-x86_64
|
||||
- libxi-devel-cos7-x86_64
|
||||
- libxxf86vm-cos7-x86_64
|
||||
- mesa-dri-drivers-cos7-x86_64
|
||||
- mesa-libegl-cos7-x86_64
|
||||
- mesa-libegl-devel-cos7-x86_64
|
||||
- mesa-libgl-cos7-x86_64
|
||||
- mesa-libgl-devel-cos7-x86_64
|
||||
- mold
|
||||
- pixman-cos7-x86_64
|
||||
- sed
|
||||
- sysroot_linux-64
|
||||
- xorg-x11-server-common-cos7-x86_64
|
||||
- xorg-x11-server-xvfb-cos7-x86_64
|
||||
- xorg-xproto
|
||||
|
||||
- if: linux and aarch64
|
||||
then:
|
||||
- clang
|
||||
- clangxx
|
||||
- kernel-headers_linux-aarch64
|
||||
- libdrm-cos7-aarch64
|
||||
- libselinux-cos7-aarch64
|
||||
- libsepol-cos7-aarch64
|
||||
- libspnav
|
||||
- libx11-common-cos7-aarch64
|
||||
- libx11-cos7-aarch64
|
||||
- libxau-cos7-aarch64
|
||||
- libxcb-cos7-aarch64
|
||||
- libxdamage-cos7-aarch64
|
||||
- libxext-cos7-aarch64
|
||||
- libxfixes-cos7-aarch64
|
||||
- libxi-cos7-aarch64
|
||||
- libxi-devel-cos7-aarch64
|
||||
- libxxf86vm-cos7-aarch64
|
||||
- mesa-dri-drivers-cos7-aarch64
|
||||
- mesa-libegl-cos7-aarch64
|
||||
- mesa-libegl-devel-cos7-aarch64
|
||||
- mesa-libgl-cos7-aarch64
|
||||
- mesa-libgl-devel-cos7-aarch64
|
||||
- mold
|
||||
- pixman-cos7-aarch64
|
||||
- sed
|
||||
- sysroot_linux-aarch64
|
||||
- xorg-x11-server-common-cos7-aarch64
|
||||
- xorg-x11-server-xvfb-cos7-aarch64
|
||||
- xorg-xproto
|
||||
|
||||
- if: build_platform != target_platform
|
||||
then:
|
||||
- cross-python_${{ target_platform }}
|
||||
|
||||
host:
|
||||
- coin3d
|
||||
- eigen
|
||||
- fmt
|
||||
- freetype
|
||||
- hdf5
|
||||
- libboost-devel
|
||||
- matplotlib-base
|
||||
- noqt5
|
||||
- numpy
|
||||
- occt
|
||||
- pcl
|
||||
- pivy
|
||||
- ply
|
||||
- pybind11
|
||||
- pyside6
|
||||
- python>=3.11,<3.12
|
||||
- qt6-main<6.9
|
||||
- six
|
||||
- smesh
|
||||
- vtk
|
||||
- xerces-c
|
||||
- yaml-cpp
|
||||
- zlib
|
||||
|
||||
- if: win
|
||||
then:
|
||||
- winpthreads-devel
|
||||
- tbb-devel
|
||||
|
||||
- if: unix
|
||||
then:
|
||||
- sed
|
||||
|
||||
- if: linux
|
||||
then:
|
||||
- libspnav
|
||||
- xorg-xproto
|
||||
|
||||
- if: osx
|
||||
then:
|
||||
- blas * accelerate*
|
||||
|
||||
run:
|
||||
- blas
|
||||
- blinker
|
||||
- calculix
|
||||
- debugpy
|
||||
- docutils
|
||||
- gmsh
|
||||
- graphviz
|
||||
- ifcopenshell
|
||||
- jinja2
|
||||
- lark
|
||||
- lxml
|
||||
- matplotlib-base
|
||||
- nine
|
||||
- noqt5
|
||||
- numpy
|
||||
- occt
|
||||
- olefile
|
||||
- opencamlib
|
||||
- opencv
|
||||
- pandas
|
||||
- pip
|
||||
- pivy
|
||||
- ply
|
||||
- pycollada
|
||||
- pyside6
|
||||
- python>=3.11,<3.12
|
||||
- pythonocc-core
|
||||
- pyyaml
|
||||
- qt6-main<6.9
|
||||
- requests
|
||||
- scipy
|
||||
- sympy
|
||||
- vtk
|
||||
- xlutils
|
||||
|
||||
- if: linux
|
||||
then:
|
||||
- libspnav
|
||||
13
package/rattler-build/scripts/disable_git_info.patch
Normal file
13
package/rattler-build/scripts/disable_git_info.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/src/Tools/SubWCRev.py b/src/Tools/SubWCRev.py
|
||||
index 1f3f0a436343..c314003736f1 100644
|
||||
--- a/src/Tools/SubWCRev.py
|
||||
+++ b/src/Tools/SubWCRev.py
|
||||
@@ -523,7 +523,7 @@ def main():
|
||||
inp = open("%s/src/Build/Version.h.in" % (bindir))
|
||||
lines = inp.readlines()
|
||||
inp.close()
|
||||
- lines = i.writeVersion(lines)
|
||||
+ #lines = i.writeVersion(lines)
|
||||
out = open("%s/src/Build/Version.h.out" % (bindir), "w")
|
||||
out.writelines(lines)
|
||||
out.write("\n")
|
||||
88
package/rattler-build/scripts/fix_macos_lib_paths.py
Normal file
88
package/rattler-build/scripts/fix_macos_lib_paths.py
Normal file
@@ -0,0 +1,88 @@
|
||||
import os
|
||||
import subprocess
|
||||
import re
|
||||
import sys
|
||||
|
||||
if len(sys.argv) < 1 or "-h" in sys.argv:
|
||||
print("""Usage: python fix_macos_paths.py <scan_path> [-r] [-s]
|
||||
|
||||
Options:
|
||||
-r scan the directory recursively
|
||||
-s scan only without fixing absolute paths in LC_RPATH or LC_REEXPORT_DYLIB
|
||||
""")
|
||||
sys.exit(1)
|
||||
|
||||
scan_path = os.path.abspath(os.path.expanduser(sys.argv[1]))
|
||||
recursive = "-r" in sys.argv
|
||||
scanmode = "-s" in sys.argv
|
||||
|
||||
def get_lc_paths(output):
|
||||
if "is not an object file" in output:
|
||||
return [], []
|
||||
|
||||
rpath_result = []
|
||||
reexport_result = []
|
||||
|
||||
matches = re.finditer(r'cmd LC_RPATH', output)
|
||||
for match in matches:
|
||||
pos = match.start(0)
|
||||
|
||||
path_match = re.search(r'path (.*) \(offset.+?\)', output[pos:])
|
||||
rpath_result.append(path_match.group(1))
|
||||
|
||||
matches = re.finditer(r'cmd LC_REEXPORT_DYLIB', output)
|
||||
for match in matches:
|
||||
pos = match.start(0)
|
||||
|
||||
path_match = re.search(r'name (.*) \(offset.+?\)', output[pos:])
|
||||
reexport_result.append(path_match.group(1))
|
||||
|
||||
return rpath_result, reexport_result
|
||||
|
||||
def remove_rpath(file_path, rpath):
|
||||
subprocess.run(['install_name_tool', '-delete_rpath', rpath, file_path])
|
||||
subprocess.run(['codesign', '--force', '--sign', '-', file_path])
|
||||
print(f'\nRemoved rpath {rpath} from {file_path}')
|
||||
|
||||
def change_reexport_dylib(file_path, reexport_dylib):
|
||||
rel_reexport_dylib = "@rpath/" + os.path.basename(reexport_dylib)
|
||||
subprocess.run(['install_name_tool', '-change', reexport_dylib, rel_reexport_dylib, file_path])
|
||||
subprocess.run(['codesign', '--force', '--sign', '-', file_path])
|
||||
print(f'\nChanged reexport dylib {reexport_dylib} to {rel_reexport_dylib} in {file_path}')
|
||||
|
||||
def scan_directory(directory, recursive=False):
|
||||
if recursive:
|
||||
print(f"Recursively scanning dir: {scan_path}")
|
||||
else:
|
||||
print(f"Scanning dir: {scan_path}")
|
||||
|
||||
for filename in os.listdir(directory):
|
||||
full_path = os.path.join(directory, filename)
|
||||
if recursive and os.path.isdir(full_path):
|
||||
scan_directory(full_path, recursive)
|
||||
continue
|
||||
elif not os.path.isfile(full_path) or os.path.islink(full_path):
|
||||
continue
|
||||
|
||||
try:
|
||||
output = subprocess.check_output(['otool', '-l', full_path], text=True)
|
||||
rpaths, reexport_dylibs = get_lc_paths(output)
|
||||
except:
|
||||
continue
|
||||
|
||||
file_dir = os.path.dirname(full_path)
|
||||
for rpath in rpaths:
|
||||
if os.path.isabs(rpath) and os.path.samefile(file_dir, rpath):
|
||||
if scanmode:
|
||||
print(f'\nFound absolute path in LC_RPATH: {rpath}\nIn: {full_path}')
|
||||
else:
|
||||
remove_rpath(full_path, rpath)
|
||||
for reexport_dylib in reexport_dylibs:
|
||||
if os.path.isabs(reexport_dylib):
|
||||
if scanmode:
|
||||
print(f'\nFound absolute path inLC_REEXPORT_DYLIB: {reexport_dylib}\nIn: {full_path}')
|
||||
else:
|
||||
change_reexport_dylib(full_path, reexport_dylib)
|
||||
|
||||
scan_directory(scan_path, recursive)
|
||||
print("Done")
|
||||
53
package/rattler-build/scripts/get_freecad_version.py
Normal file
53
package/rattler-build/scripts/get_freecad_version.py
Normal file
@@ -0,0 +1,53 @@
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
import platform
|
||||
from datetime import datetime
|
||||
|
||||
import freecad
|
||||
import FreeCAD
|
||||
|
||||
package_manager = "conda"
|
||||
system = platform.platform().split("-")[0]
|
||||
arch = platform.machine()
|
||||
|
||||
# Windows uses a different syntax
|
||||
if arch == "AMD64":
|
||||
arch = "x86_64"
|
||||
|
||||
if "ARCH" in os.environ:
|
||||
if os.environ["ARCH"] != "":
|
||||
arch = os.environ["ARCH"]
|
||||
|
||||
python_version = platform.python_version().split(".")
|
||||
python_version = "py" + python_version[0] + python_version[1]
|
||||
date = str(datetime.now()).split(" ")[0]
|
||||
|
||||
version_info = FreeCAD.Version()
|
||||
build_version_suffix = FreeCAD.ConfigGet("BuildVersionSuffix")
|
||||
dev_version = version_info[0] + "." + version_info[1] + "." + version_info[2] + build_version_suffix
|
||||
revision = version_info[3].split(" ")[0]
|
||||
|
||||
if system == "macOS":
|
||||
import jinja2
|
||||
print("create plist from template")
|
||||
osx_directory = os.path.join(os.path.dirname(__file__), "..", "osx")
|
||||
with open(os.path.join(osx_directory, "Info.plist.template")) as template_file:
|
||||
template_str = template_file.read()
|
||||
template = jinja2.Template(template_str)
|
||||
rendered_str = template.render( FREECAD_VERSION="{}-{}".format(dev_version, revision),
|
||||
APPLICATION_MENU_NAME="FreeCAD-{}-{}".format(dev_version, revision) )
|
||||
with open(os.path.join(osx_directory, "FreeCAD.app", "Contents", "Info.plist"), "w") as rendered_file:
|
||||
rendered_file.write(rendered_str)
|
||||
|
||||
if "DEPLOY_RELEASE" in os.environ and os.environ["DEPLOY_RELEASE"] == "weekly-builds":
|
||||
dev_version = "weekly-builds"
|
||||
revision_separator = "-"
|
||||
else:
|
||||
revision_separator = ""
|
||||
revision = ""
|
||||
|
||||
bundle_name = f"FreeCAD_{dev_version}{revision_separator}{revision}-{package_manager}-{system}-{arch}-{python_version}"
|
||||
|
||||
with open("bundle_name.txt", "w") as bundle_name_file:
|
||||
bundle_name_file.write(bundle_name)
|
||||
41
package/rattler-build/scripts/make_version_file.py
Executable file
41
package/rattler-build/scripts/make_version_file.py
Executable file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# call this file from within the FreeCAD git repo
|
||||
# this script creates a file with the important version information
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
sys.path.append(f"{os.getcwd()}/src/Tools")
|
||||
import SubWCRev
|
||||
|
||||
gitInfo = SubWCRev.GitControl()
|
||||
gitInfo.extractInfo("","")
|
||||
i = open("src/Build/Version.h.cmake")
|
||||
content = []
|
||||
for line in i.readlines():
|
||||
line = line.replace("${PACKAGE_WCREF}",gitInfo.rev)
|
||||
line = line.replace("${PACKAGE_WCDATE}",gitInfo.date)
|
||||
line = line.replace("${PACKAGE_WCURL}",gitInfo.url)
|
||||
content.append(line)
|
||||
|
||||
with open("src/Build/Version.h.cmake", "w") as o:
|
||||
content.append('// Git relevant stuff\n')
|
||||
content.append('#define FCRepositoryHash "%s"\n' % (gitInfo.hash))
|
||||
content.append('#define FCRepositoryBranch "%s"\n' % (gitInfo.branch))
|
||||
o.writelines(content)
|
||||
|
||||
with open(os.sys.argv[1], "w") as f:
|
||||
f.write(f"rev_number: {gitInfo.rev}\n")
|
||||
f.write(f"branch_name: {gitInfo.branch}\n")
|
||||
f.write(f"commit_date: {gitInfo.date}\n")
|
||||
f.write(f"commit_hash: {gitInfo.hash}\n")
|
||||
f.write(f"remote_url: {gitInfo.url}\n")
|
||||
|
||||
p = subprocess.Popen(["git", "-c", "user.name='github-actions[bot]'", "-c", "user.email='41898282+github-actions[bot]@users.noreply.github.com'",
|
||||
"commit", "-a", "-m", "add git information"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
out, err = p.communicate()
|
||||
|
||||
print(out.decode())
|
||||
print(err.decode())
|
||||
56
package/rattler-build/windows/create_bundle.bat
Normal file
56
package/rattler-build/windows/create_bundle.bat
Normal file
@@ -0,0 +1,56 @@
|
||||
set conda_env="fc_env"
|
||||
|
||||
robocopy ..\.pixi\envs\default\* %conda_env% /S /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
|
||||
%conda_env%\python ..\scripts\get_freecad_version.py
|
||||
set /p freecad_version_name= <bundle_name.txt
|
||||
|
||||
echo **********************
|
||||
echo %freecad_version_name%
|
||||
echo **********************
|
||||
|
||||
REM remove arm binaries that fail to extract unless using latest 7zip
|
||||
for /r %conda_env% %%i in (*arm*.exe) do (@echo "%%i will be removed" & @del "%%i")
|
||||
|
||||
set copy_dir="FreeCAD_Conda_Build"
|
||||
mkdir %copy_dir%
|
||||
|
||||
REM Copy Conda's Python and (U)CRT to FreeCAD/bin
|
||||
robocopy %conda_env%\DLLs %copy_dir%\bin\DLLs /S /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\Lib %copy_dir%\bin\Lib /XD __pycache__ /S /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\Scripts %copy_dir%\bin\Scripts /S /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\python*.* %copy_dir%\bin\ /XF *.pdb /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\msvc*.* %copy_dir%\bin\ /XF *.pdb /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\ucrt*.* %copy_dir%\bin\ /XF *.pdb /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
REM Copy meaningful executables
|
||||
robocopy %conda_env%\Library\bin %copy_dir%\bin\ ccx.exe /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\Library\bin %copy_dir%\bin\ gmsh.exe /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\Library\bin %copy_dir%\bin\ dot.exe /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\Library\bin %copy_dir%\bin\ unflatten.exe /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\Library\mingw-w64\bin * %copy_dir%\bin\ /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
REM Copy Conda's QT5/plugins to FreeCAD/bin
|
||||
robocopy %conda_env%\Library\plugins %copy_dir%\bin\ /S /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\Library\resources %copy_dir%\resources /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\Library\translations %copy_dir%\translations /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
REM get all the dependency .dlls
|
||||
robocopy %conda_env%\Library\bin *.dll %copy_dir%\bin /XF *.pdb /XF api*.* /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
REM Copy FreeCAD build
|
||||
robocopy %conda_env%\Library\bin FreeCAD* %copy_dir%\bin /XF *.pdb /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\Library\data %copy_dir%\data /XF *.txt /S /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\Library\Ext %copy_dir%\Ext /S /XD __pycache__ /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\Library\lib %copy_dir%\lib /XF *.lib /XF *.prl /XF *.sh /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\Library\Mod %copy_dir%\Mod /S /XD __pycache__ /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
robocopy %conda_env%\Library\doc %copy_dir%\doc ThirdPartyLibraries.html LICENSE.html /MT:%NUMBER_OF_PROCESSORS% > nul
|
||||
REM Apply Patches
|
||||
rename %copy_dir%\bin\Lib\ssl.py ssl-orig.py
|
||||
copy ssl-patch.py %copy_dir%\bin\Lib\ssl.py
|
||||
|
||||
cd %copy_dir%\..
|
||||
ren %copy_dir% %freecad_version_name%
|
||||
dir
|
||||
|
||||
REM if errorlevel1 exit 1
|
||||
|
||||
"%ProgramFiles%\7-Zip\7z.exe" a -t7z -mx9 -mmt=%NUMBER_OF_PROCESSORS% %freecad_version_name%.7z %freecad_version_name%\ -bb
|
||||
certutil -hashfile "%freecad_version_name%.7z" SHA256 > "%freecad_version_name%.7z"-SHA256.txt
|
||||
echo %date%-%time% >>"%freecad_version_name%.7z"-SHA256.txt
|
||||
78
package/rattler-build/windows/create_bundle.sh
Normal file
78
package/rattler-build/windows/create_bundle.sh
Normal file
@@ -0,0 +1,78 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
conda_env="fc_env"
|
||||
|
||||
mkdir -p ${conda_env}
|
||||
|
||||
cp -a ../.pixi/envs/default/* ${conda_env}
|
||||
|
||||
export PATH="${PWD}/${conda_env}/bin:${PATH}"
|
||||
export CONDA_PREFIX="${PWD}/${conda_env}"
|
||||
|
||||
# remove arm binaries that fail to extract unless using latest 7zip
|
||||
rm $(find ${conda_env} -name \*arm\*.exe)
|
||||
|
||||
# delete unnecessary stuff
|
||||
rm -rf ${conda_env}/include
|
||||
find ${conda_env} -name \*.a -delete
|
||||
|
||||
copy_dir="FreeCAD_Conda_Build"
|
||||
mkdir -p ${copy_dir}/bin
|
||||
|
||||
# Copy Conda's Python and (U)CRT to FreeCAD/bin
|
||||
cp -a ${conda_env}/DLLs ${copy_dir}/bin/DLLs
|
||||
cp -a ${conda_env}/Lib ${copy_dir}/bin/Lib
|
||||
cp -a ${conda_env}/Scripts ${copy_dir}/bin/Scripts
|
||||
cp -a ${conda_env}/python*.* ${copy_dir}/bin
|
||||
cp -a ${conda_env}/msvc*.* ${copy_dir}/bin
|
||||
cp -a ${conda_env}/ucrt*.* ${copy_dir}/bin
|
||||
# Copy meaningful executables
|
||||
cp -a ${conda_env}/Library/bin/ccx.exe ${copy_dir}/bin
|
||||
cp -a ${conda_env}/Library/bin/gmsh.exe ${copy_dir}/bin
|
||||
cp -a ${conda_env}/Library/bin/dot.exe ${copy_dir}/bin
|
||||
cp -a ${conda_env}/Library/bin/unflatten.exe ${copy_dir}/bin
|
||||
cp -a ${conda_env}/Library/mingw-w64/bin/* ${copy_dir}/bin
|
||||
# copy resources -- perhaps needs reduction
|
||||
cp -a ${conda_env}/Library/share ${copy_dir}/share
|
||||
# get all the dependency .dlls
|
||||
cp -a ${conda_env}/Library/bin/*.dll ${copy_dir}/bin
|
||||
# Copy FreeCAD build
|
||||
cp -a ${conda_env}/Library/bin/freecad* ${copy_dir}/bin
|
||||
cp -a ${conda_env}/Library/bin/FreeCAD* ${copy_dir}/bin
|
||||
cp -a ${conda_env}/Library/data ${copy_dir}/data
|
||||
cp -a ${conda_env}/Library/Ext ${copy_dir}/Ext
|
||||
cp -a ${conda_env}/Library/lib ${copy_dir}/lib
|
||||
cp -a ${conda_env}/Library/Mod ${copy_dir}/Mod
|
||||
rm -rf ${conda_env}/bin_tmp
|
||||
|
||||
# Apply Patches
|
||||
mv ${copy_dir}/bin/Lib/ssl.py ssl-orig.py
|
||||
cp ssl-patch.py ${copy_dir}/bin/Lib/ssl.py
|
||||
|
||||
echo '[Paths]' >> ${copy_dir}/bin/qt6.conf
|
||||
echo 'Prefix = ../lib/qt6' >> ${copy_dir}/bin/qt6.conf
|
||||
|
||||
python_version=$(python -c 'import platform; print("py" + platform.python_version_tuple()[0] + platform.python_version_tuple()[1])')
|
||||
version_name="FreeCAD_${BUILD_TAG}-Windows-$(uname -m)-${python_version}"
|
||||
|
||||
echo -e "################"
|
||||
echo -e "version_name: ${version_name}"
|
||||
echo -e "################"
|
||||
|
||||
pixi list -e default > ${copy_dir}/packages.txt
|
||||
sed -i '1s/.*/\nLIST OF PACKAGES:/' ${copy_dir}/packages.txt
|
||||
|
||||
mv ${copy_dir} ${version_name}
|
||||
|
||||
"${PROGRAMFILES}/7-Zip/7z.exe" a -t7z -mx9 -mmt=${NUMBER_OF_PROCESSORS} ${version_name}.7z ${version_name} -bb
|
||||
|
||||
# create hash
|
||||
sha256sum ${version_name}.7z > ${version_name}.7z-SHA256.txt
|
||||
|
||||
if [ "${UPLOAD_RELEASE}" == "true" ]; then
|
||||
gh release create ${BUILD_TAG} --title "Weekly Build ${BUILD_TAG}" --notes "Weekly Build ${BUILD_TAG}" --prerelease || true
|
||||
gh release upload --clobber ${BUILD_TAG} "${version_name}.7z" "${version_name}.7z-SHA256.txt"
|
||||
fi
|
||||
1497
package/rattler-build/windows/ssl-patch.py
Normal file
1497
package/rattler-build/windows/ssl-patch.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,7 @@ fi
|
||||
|
||||
packages=(
|
||||
ccache
|
||||
cmake
|
||||
doxygen
|
||||
graphviz
|
||||
imagemagick
|
||||
|
||||
63
pixi.toml
63
pixi.toml
@@ -7,12 +7,15 @@ channels = ["conda-forge"]
|
||||
platforms = [ "linux-64", "linux-aarch64", "osx-64", "osx-arm64", "win-64" ]
|
||||
|
||||
[dependencies]
|
||||
blinker = "*"
|
||||
calculix = "*"
|
||||
ccache = "*"
|
||||
cmake = "3.28.3"
|
||||
cmake = "*"
|
||||
coin3d = "*"
|
||||
compilers = "*"
|
||||
conda-devenv = "*"
|
||||
debugpy = "*"
|
||||
docutils = "*"
|
||||
doxygen = "*"
|
||||
eigen = "*"
|
||||
fmt = "*"
|
||||
@@ -20,35 +23,50 @@ freetype = "*"
|
||||
git = "*"
|
||||
graphviz = "*"
|
||||
hdf5 = "*"
|
||||
ifcopenshell = "*"
|
||||
lark = "*"
|
||||
libboost-devel = "*"
|
||||
lxml = "*"
|
||||
matplotlib = "*"
|
||||
nine = "*"
|
||||
ninja = "*"
|
||||
noqt5 = "*"
|
||||
numpy = "*"
|
||||
occt = "*"
|
||||
opencamlib = "*"
|
||||
opencv = "*"
|
||||
openssl = "*"
|
||||
pandas = "*"
|
||||
pcl = "*"
|
||||
pip = "*"
|
||||
pivy = "*"
|
||||
ply = "*"
|
||||
pre-commit = "*"
|
||||
pybind11 = "*"
|
||||
pycollada = "*"
|
||||
pyside6 = "*"
|
||||
python = "3.13"
|
||||
python = ">=3.11,<3.12"
|
||||
pythonocc-core = "*"
|
||||
pyyaml = "*"
|
||||
qt6-main = "*"
|
||||
scipy = ">=1.14.1,<2"
|
||||
requests = "*"
|
||||
scipy = "*"
|
||||
six = "*"
|
||||
smesh = "*"
|
||||
swig = "*"
|
||||
sympy = "*"
|
||||
tbb-devel = "*"
|
||||
vtk = "*"
|
||||
xerces-c = "*"
|
||||
xlutils = "*"
|
||||
yaml-cpp = "*"
|
||||
zlib = "*"
|
||||
zstd = "*"
|
||||
|
||||
## Linux Dependencies (x86-64)
|
||||
[target.linux-64.dependencies]
|
||||
clang = "*"
|
||||
clangxx = "*"
|
||||
kernel-headers_linux-64 = "*"
|
||||
libdrm-cos7-x86_64 = "*"
|
||||
libselinux-cos7-x86_64 = "*"
|
||||
@@ -64,11 +82,13 @@ libxfixes-cos7-x86_64 = "*"
|
||||
libxi-cos7-x86_64 = "*"
|
||||
libxi-devel-cos7-x86_64 = "*"
|
||||
libxxf86vm-cos7-x86_64 = "*"
|
||||
llvm-openmp = "*"
|
||||
mesa-dri-drivers-cos7-x86_64 = "*"
|
||||
mesa-libegl-cos7-x86_64 = "*"
|
||||
mesa-libegl-devel-cos7-x86_64 = "*"
|
||||
mesa-libgl-cos7-x86_64 = "*"
|
||||
mesa-libgl-devel-cos7-x86_64 = "*"
|
||||
mold = "*"
|
||||
pixman-cos7-x86_64 = "*"
|
||||
sed = "*"
|
||||
sysroot_linux-64 = "*"
|
||||
@@ -78,6 +98,8 @@ xorg-xproto = "*"
|
||||
|
||||
## Linux Dependencies (aarch64)
|
||||
[target.linux-aarch64.dependencies]
|
||||
clang = "*"
|
||||
clangxx = "*"
|
||||
kernel-headers_linux-aarch64 = "*"
|
||||
libdrm-cos7-aarch64 = "*"
|
||||
libglvnd-cos7-aarch64 = "*"
|
||||
@@ -95,6 +117,7 @@ libxfixes-cos7-aarch64 = "*"
|
||||
libxi-cos7-aarch64 = "*"
|
||||
libxi-devel-cos7-aarch64 = "*"
|
||||
libxxf86vm-cos7-aarch64 = "*"
|
||||
llvm-openmp = "*"
|
||||
mesa-dri-drivers-cos7-aarch64 = "*"
|
||||
mesa-khr-devel-cos7-aarch64 = "*"
|
||||
mesa-libegl-cos7-aarch64 = "*"
|
||||
@@ -103,6 +126,7 @@ mesa-libgbm-cos7-aarch64 = "*"
|
||||
mesa-libgl-cos7-aarch64 = "*"
|
||||
mesa-libgl-devel-cos7-aarch64 = "*"
|
||||
mesa-libglapi-cos7-aarch64 = "*"
|
||||
mold = "*"
|
||||
pixman-cos7-aarch64 = "*"
|
||||
sed = "*"
|
||||
sysroot_linux-aarch64 = "*"
|
||||
@@ -118,31 +142,34 @@ sed = "*"
|
||||
[target.osx-arm64.dependencies]
|
||||
sed = "*"
|
||||
|
||||
[target.win-64.dependencies]
|
||||
pthreads-win32 = "*"
|
||||
|
||||
## Qt 6 Configuration Presets
|
||||
[target.linux-64.tasks]
|
||||
configure = { cmd = [ "cmake", "-B", "build", "--preset", "conda-linux-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"]}
|
||||
configure-debug = { cmd = [ "cmake", "-B", "build", "--preset", "conda-linux-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"]}
|
||||
configure-release = { cmd = [ "cmake", "-B", "build", "--preset", "conda-linux-release", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"]}
|
||||
configure = { cmd = [ "cmake", "-B", "build", "--preset", "conda-linux-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"], env={ CFLAGS="", CXXFLAGS="", DEBUG_CFLAGS="", DEBUG_CXXFLAGS="" }}
|
||||
configure-debug = { cmd = [ "cmake", "-B", "build", "--preset", "conda-linux-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"], env={ CFLAGS="", CXXFLAGS="", DEBUG_CFLAGS="", DEBUG_CXXFLAGS="" }}
|
||||
configure-release = { cmd = [ "cmake", "-B", "build", "--preset", "conda-linux-release", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"], env={ CFLAGS="", CXXFLAGS="", DEBUG_CFLAGS="", DEBUG_CXXFLAGS="" }}
|
||||
|
||||
[target.linux-aarch64.tasks]
|
||||
configure = { cmd = [ "cmake", "-B", "build", "--preset", "conda-linux-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on= ["initialize"]}
|
||||
configure-debug = { cmd = [ "cmake", "-B", "build", "--preset", "conda-linux-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on= ["initialize"]}
|
||||
configure-release = { cmd = [ "cmake", "-B", "build", "--preset", "conda-linux-release", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on= ["initialize"]}
|
||||
configure = { cmd = [ "cmake", "-B", "build", "--preset", "conda-linux-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on= ["initialize"], env={ CFLAGS="", CXXFLAGS="", DEBUG_CFLAGS="", DEBUG_CXXFLAGS="" }}
|
||||
configure-debug = { cmd = [ "cmake", "-B", "build", "--preset", "conda-linux-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on= ["initialize"], env={ CFLAGS="", CXXFLAGS="", DEBUG_CFLAGS="", DEBUG_CXXFLAGS="" }}
|
||||
configure-release = { cmd = [ "cmake", "-B", "build", "--preset", "conda-linux-release", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on= ["initialize"], env={ CFLAGS="", CXXFLAGS="", DEBUG_CFLAGS="", DEBUG_CXXFLAGS="" }}
|
||||
|
||||
[target.osx-64.tasks]
|
||||
configure = { cmd = [ "cmake", "-B", "build", "--preset", "conda-macos-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"]}
|
||||
configure-debug = { cmd = [ "cmake", "-B", "build", "--preset", "conda-macos-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"]}
|
||||
configure-release = { cmd = [ "cmake", "-B", "build", "--preset", "conda-macos-release", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"]}
|
||||
configure = { cmd = [ "cmake", "-B", "build", "--preset", "conda-macos-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"], env={ CFLAGS="", CXXFLAGS="", DEBUG_CFLAGS="", DEBUG_CXXFLAGS="" }}
|
||||
configure-debug = { cmd = [ "cmake", "-B", "build", "--preset", "conda-macos-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"], env={ CFLAGS="", CXXFLAGS="", DEBUG_CFLAGS="", DEBUG_CXXFLAGS="" }}
|
||||
configure-release = { cmd = [ "cmake", "-B", "build", "--preset", "conda-macos-release", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"], env={ CFLAGS="", CXXFLAGS="", DEBUG_CFLAGS="", DEBUG_CXXFLAGS="" }}
|
||||
|
||||
[target.osx-arm64.tasks]
|
||||
configure = { cmd = [ "cmake", "-B", "build", "--preset", "conda-macos-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"]}
|
||||
configure-debug = { cmd = [ "cmake", "-B", "build", "--preset", "conda-macos-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"]}
|
||||
configure-release = { cmd = [ "cmake", "-B", "build", "--preset", "conda-macos-release", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"]}
|
||||
configure = { cmd = [ "cmake", "-B", "build", "--preset", "conda-macos-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"], env={ CFLAGS="", CXXFLAGS="", DEBUG_CFLAGS="", DEBUG_CXXFLAGS="" }}
|
||||
configure-debug = { cmd = [ "cmake", "-B", "build", "--preset", "conda-macos-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"], env={ CFLAGS="", CXXFLAGS="", DEBUG_CFLAGS="", DEBUG_CXXFLAGS="" }}
|
||||
configure-release = { cmd = [ "cmake", "-B", "build", "--preset", "conda-macos-release", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"], env={ CFLAGS="", CXXFLAGS="", DEBUG_CFLAGS="", DEBUG_CXXFLAGS="" }}
|
||||
|
||||
[target.win-64.tasks]
|
||||
configure = { cmd = [ "cmake", "-B", "build", "--preset", "conda-windows-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"]}
|
||||
configure-debug = { cmd = [ "cmake", "-B", "build", "--preset", "conda-windows-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"]}
|
||||
configure-release = { cmd = [ "cmake", "-B", "build", "--preset", "conda-windows-release", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF" ], depends-on = ["initialize"]}
|
||||
configure = { cmd = [ "cmake", "-B", "build", "--preset", "conda-windows-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF", "-DCMAKE_GENERATOR_PLATFORM=", "-DCMAKE_GENERATOR_TOOLSET=" ], depends-on = ["initialize"], env={ CFLAGS="", CXXFLAGS="", DEBUG_CFLAGS="", DEBUG_CXXFLAGS="" }}
|
||||
configure-debug = { cmd = [ "cmake", "-B", "build", "--preset", "conda-windows-debug", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF", "-DCMAKE_GENERATOR_PLATFORM=", "-DCMAKE_GENERATOR_TOOLSET=" ], depends-on = ["initialize"], env={ CFLAGS="", CXXFLAGS="", DEBUG_CFLAGS="", DEBUG_CXXFLAGS="" }}
|
||||
configure-release = { cmd = [ "cmake", "-B", "build", "--preset", "conda-windows-release", "-DFREECAD_QT_VERSION=6", "-DBUILD_REVERSEENGINEERING=OFF", "-DCMAKE_GENERATOR_PLATFORM=", "-DCMAKE_GENERATOR_TOOLSET=" ], depends-on = ["initialize"], env={ CFLAGS="", CXXFLAGS="", DEBUG_CFLAGS="", DEBUG_CXXFLAGS="" }}
|
||||
freecad = { cmd = [ ".pixi/envs/default/Library/bin/FreeCAD.exe" ], depends-on = ["install"]}
|
||||
|
||||
## Tasks
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
area==1.1.1
|
||||
cog==0.6.1
|
||||
ConfigParser==5.3.0
|
||||
ConfigParser==7.2.0
|
||||
defusedxml==0.7.1
|
||||
ifcopenshell==0.7.0.230318
|
||||
ladybug-core==0.42.2
|
||||
matplotlib==3.6.3
|
||||
numpy==1.24.2
|
||||
opencamlib==2023.1.11
|
||||
packaging==23.0
|
||||
packaging==24.2
|
||||
Pivy==0.6.8
|
||||
ply==3.11
|
||||
debugpy==1.6.7
|
||||
debugpy==1.8.14
|
||||
pyNastran==1.3.4
|
||||
pyshp==2.3.1
|
||||
PySide2==5.15.2.1
|
||||
|
||||
9
src/3rdParty/CMakeLists.txt
vendored
9
src/3rdParty/CMakeLists.txt
vendored
@@ -4,7 +4,14 @@ if (BUILD_SMESH)
|
||||
endif()
|
||||
|
||||
add_subdirectory(lazy_loader)
|
||||
add_subdirectory(libE57Format)
|
||||
|
||||
if(NOT FREECAD_USE_EXTERNAL_E57FORMAT)
|
||||
add_subdirectory(libE57Format)
|
||||
endif()
|
||||
|
||||
if(BUILD_MATERIAL_EXTERNAL)
|
||||
add_subdirectory(lru-cache)
|
||||
endif()
|
||||
|
||||
if (BUILD_ASSEMBLY AND NOT FREECAD_USE_EXTERNAL_ONDSELSOLVER)
|
||||
if( NOT EXISTS "${CMAKE_SOURCE_DIR}/src/3rdParty/OndselSolver/CMakeLists.txt" )
|
||||
|
||||
2
src/3rdParty/libkdtree/CMakeLists.txt
vendored
2
src/3rdParty/libkdtree/CMakeLists.txt
vendored
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required (VERSION 2.8.12)
|
||||
project (libkdtree CXX)
|
||||
cmake_minimum_required (VERSION 2.6.0)
|
||||
|
||||
option (BUILD_PYTHON_BINDINGS "Build Python bindings (requires SWIG)")
|
||||
|
||||
|
||||
2
src/3rdParty/libkdtree/COPYING
vendored
2
src/3rdParty/libkdtree/COPYING
vendored
@@ -1,6 +1,6 @@
|
||||
"The Artistic Licence 2.0"
|
||||
Copyright (c) 2000-2006, The Perl Foundation.
|
||||
https://www.perlfoundation.org/artistic-license-20.html
|
||||
http://www.perlfoundation.org/legal/licenses/artistic-2_0.html
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||
document, but changing it is not allowed.
|
||||
|
||||
236
src/3rdParty/libkdtree/ChangeLog
vendored
236
src/3rdParty/libkdtree/ChangeLog
vendored
@@ -1,236 +0,0 @@
|
||||
libkdtree++ ChangeLog
|
||||
=====================
|
||||
|
||||
2008-11-17 Sylvain Bougerel <sylvain.bougerel@asia.thalesgroup.com>
|
||||
|
||||
- Added #include<cstdio> in order to compile 'printf' statements in the
|
||||
file 'examples/test_find_within_range.cpp'.
|
||||
- Added patch from Max Fellermann in order to compile libkdtree++ with
|
||||
clang++.
|
||||
|
||||
2009-02-10 Paul Harris <paulharris@computer.org>
|
||||
|
||||
- Bug fix: was incorrectly casting a pointer when the search key type
|
||||
was different to the stored type.
|
||||
|
||||
2008-12-30 Paul Harris <paulharris@computer.org>
|
||||
|
||||
- New function: efficient_replace_and_optimise().
|
||||
Yes, its a long name. Sylvain doesn't like it.
|
||||
The reason for the long name is that it is a dangerous function,
|
||||
and it will resort whatever vector<> of data that you pass it.
|
||||
So I wanted the user to really know what they were doing before
|
||||
they called this function.
|
||||
- Now calls sqrt() when required in order to search for items
|
||||
in 'real' distance units... And so it will accept and return distance
|
||||
in 'real' units (as opposed to squared units).
|
||||
This is not an ideal solution, we have all sorts of ideas to improve
|
||||
kdtree which will include less calls to sqrt() for more speed, and
|
||||
the ability to change the standard euclidean distance measurements
|
||||
for distance-on-a-sphere or whatever the user wants.
|
||||
- Changed from using std::sort() to std::nth_element() when optimising
|
||||
the tree. Performance boost.
|
||||
- Added lots of tests to check that the find functions are working
|
||||
correctly when fed edge-cases, including:
|
||||
- Items that are exactly 'max' distance away from the target.
|
||||
- When there are no value items to find.
|
||||
- Templated the find functions so that the target/center point can be
|
||||
anything that can be accessed via the Accessor.
|
||||
- Fixes to make it compile.
|
||||
|
||||
- And, a Python wrapper ! See README.Python
|
||||
|
||||
- CMake support now can build the python wrapper and install the headers
|
||||
and the python wrapper to a destination folder. Its simple, but neat.
|
||||
Does not install python module into the python site packages or anything
|
||||
like that.
|
||||
|
||||
2008-11-17 Sylvain Bougerel <sylvain.bougerel@asia.thalesgroup.com>
|
||||
|
||||
- The version number of the library is now part of the headers.
|
||||
- Fixed a bug with assignment operator.
|
||||
- Fixed uninitialized memory problem with valgrind, when printing the
|
||||
content of the tree. Due to the fact the _M_header was a _Link_type
|
||||
instead of a _Node_base type and _M_root was a _Base_ptr type instead of
|
||||
a _Link_type.
|
||||
- Paul Harris fixed find() by ensuring that the correct node is being
|
||||
matched during a find(). Thus, fixed a similar problem in erase. Paul
|
||||
also added a new test courtesy of Hayne.
|
||||
- Paul Harris augmented test_kdtree with various test on copy
|
||||
construction, assignment, and formatting operator.
|
||||
- Paul Harris added support for CMake, which should suit not only
|
||||
MSVC users but others too.
|
||||
- Paul Harris fixed bug with compiling with MSVC2005 with the 64bit
|
||||
warnings turned on.
|
||||
|
||||
2008-11-12 Sylvain Bougerel <sylvain.bougerel@asia.thalesgroup.com>
|
||||
|
||||
- Fix segfault on the regular iterator when _M_header->_M_right ==
|
||||
_M_root. Fix segfault on the reverse iterator when _M_header->_M_left ==
|
||||
_M_root.
|
||||
|
||||
Besides, it also change the behavior when iterating past the end() or
|
||||
rend(). Previously this would result in segfaults, now it makes the
|
||||
iterator points to an undetermined location in the tree, similarly to
|
||||
the current implementation of GNU libstdc++.
|
||||
|
||||
2008-11-10 Sylvain Bougerel <sylvain.bougerel@asia.thalesgroup.com>
|
||||
|
||||
- kdtree++/iterator.hpp (KDTree): the decrement iterator was
|
||||
ill-written. Its buggy behavior, and the use of non-standard
|
||||
reverse_iterator initialiser needed to be fixed. These error were do to
|
||||
a previous failed attempt by me at fixing the reverse_iterator.
|
||||
|
||||
This time, I believe I got it right, however it needed the kdtree
|
||||
structure to be modified. The reason is that without modification it is
|
||||
not possible to distinguish the "header" from the "root" within the
|
||||
iterator. This is required for the reverse_iterator to work properly.
|
||||
|
||||
Now the kdtree has an additional pointer that points directly to the
|
||||
root. The parent pointer of the header is permanently null. And
|
||||
therefore the header can be distinguished from the root within the
|
||||
iterator by checking the parent of the current node: if it is null, we
|
||||
are at the header.
|
||||
|
||||
|
||||
2008-11-10 Sylvain Bougerel (sylvain.bougerel.devel@gmail.com)
|
||||
|
||||
- patch from Martin Shreiber to make libkdtree to compile with newer
|
||||
version of g++-4.2 and g++4.3.
|
||||
|
||||
- patch from Paul Harris to make libkdtree more exception transparent.
|
||||
|
||||
2007-12-08 Sylvain Bougerel (sylvain.bougerel.devel@gmail.com)
|
||||
|
||||
- fix bug where find_nearest() could return the wrong value if a
|
||||
maximum distance greater than the root distance to the target value
|
||||
was given in argument to the function.
|
||||
|
||||
- find_nearest() still returns SQUARED value of the distance. You still
|
||||
have to use sqrt() on the second member of the iterator.
|
||||
|
||||
- find_nearest() behavior was slightly changed: if many nodes are at
|
||||
the same distance from the target value, the node with the lowest
|
||||
memory address will be returned. This is to catter for the
|
||||
reimplementation of find_exact() coming soon.
|
||||
|
||||
2007-12-02 Sylvain Bougerel (sylvain.bougerel.devel@gmail.com)
|
||||
|
||||
- find_nearest() now returned the SQUARED value of the distance for
|
||||
euclidean space calculation (the default). You have to use sqrt() on
|
||||
the returned distance (i.e. iterator->second) if you want to read the
|
||||
absolute distance returned by find_nearest. My apologies for not
|
||||
making highlighting this beforehand.
|
||||
|
||||
- Increased the performance of find and find_nearest/find_nearest_if by
|
||||
about 50x to 100x depending on your compilation flags.
|
||||
|
||||
- KDTree are not defined as:
|
||||
KDTree<__K, _Val, _Acc, _Cmp, _Alloc>
|
||||
but as:
|
||||
KDTree<__K, _Val, _Acc, _Dist, _Cmp, _Alloc>
|
||||
So pay attention to the _Dist functor. The distance functor calculate
|
||||
the squared difference between 2 elements returned by the accessor. You
|
||||
might have to change your code to reflect the new definition, or it wont
|
||||
compile if you have set custom accessor and comparison functors.
|
||||
|
||||
- The following functors are now accessible in the tree:
|
||||
- the comparison functor, accessible by copy only
|
||||
- the accessor functor, accessible by copy only
|
||||
- the distance functor, accessible read-write, this means that
|
||||
you can modify the behavior of find, find_nearest,
|
||||
find_nearest_if within the same KDTree object.
|
||||
|
||||
- find_exact has not be modified and retained the code of the former,
|
||||
slower algorithm. I have to write some more code to do this. Pls wait a
|
||||
little more.
|
||||
|
||||
- The file accessor.hpp was renamed as function.hpp for it now boast
|
||||
more than just the KDTree accessor
|
||||
|
||||
2007-11-25 Sylvain Bougerel (sylvain.bougerel.devel@gmail.com)
|
||||
|
||||
- fixed the reverse_iterator. Now it can be used.
|
||||
|
||||
2007-10-24 Sylvain Bougerel (sylvain.bougerel.devel@gmail.com)
|
||||
|
||||
- Removal of all the warnings that are yield by the compiler when
|
||||
using the following flags:
|
||||
-Wall -pedantic -ansi
|
||||
Do not hesitate to suggest any flags for additional code checking.
|
||||
|
||||
This release also feature numerous of enhancements by Paul Harris
|
||||
(paulharris@computer.org):
|
||||
- const kdtrees can be searched
|
||||
- find_nearest_if() enforce validation of a predicate
|
||||
- visit_within_range() walk the tree and calls
|
||||
Visitor::operator() on template argument <Visitor> for
|
||||
each node within the range
|
||||
- find_exact() matches an kdtree::value_type by location and by
|
||||
calling kdtree::value_type::operator==() (in case two different
|
||||
items have the same location find_exact() will not return the
|
||||
wrong item)
|
||||
- erase_exact() is to erase() what find_exact() is to find()
|
||||
- check_tree() and num_dist_calcs for debugging purpose plus
|
||||
additional improvements on erase and region intersection
|
||||
|
||||
2004-11-26 Paul Harris (paulharris@computer.org)
|
||||
|
||||
- New feature: find_nearest()
|
||||
- Accessors can now be initialised with the tree, so ptr_fun()
|
||||
or functors can be used to access datapoints.
|
||||
- Accessors now much more generic, so you can use the same
|
||||
accessor to access multiple types.
|
||||
- Range-constructors now optimise() automatically, simplifying
|
||||
the construction of a filled tree.
|
||||
- _Range is now more easy to construct.
|
||||
|
||||
2004-11-15 Martin F. Krafft (libkdtree@pobox.madduck.net)
|
||||
|
||||
- fixed numerous little bugs that led to compilation problems
|
||||
- changed code to compile cleanly with GCC 3.4 and GCC 4.0
|
||||
|
||||
2004-11-06 Martin F. Krafft (libkdtree@pobox.madduck.net)
|
||||
|
||||
- reverted to optimise() to prevent API change, and added an optimize()
|
||||
passthrough method with an appropriate comment.
|
||||
|
||||
2004-11-05 Paul Harris (paulharris@computer.org)
|
||||
|
||||
- Renamed optimise() to optimize().
|
||||
- Added a full set of range constructors and insert(range) methods.
|
||||
it now works with inserter(tree,tree.begin())
|
||||
- Target type no longer needs a default constructor. This also fixes
|
||||
problems with empty trees (would crash if optimized).
|
||||
- Some code cleanup (removed inlines, switched from const_iterator to
|
||||
iterator, added this-> to ensure the methods are called).
|
||||
- Added a new method: count_within_range().
|
||||
- Fixed bug in rend().
|
||||
|
||||
2004-11-04 Martin F. Krafft (libkdtree@pobox.madduck.net)
|
||||
|
||||
- Integrated patch by Paul Harris to fix a logic error pertaining to
|
||||
OutputIterators in find_within_range. find_within_range() now
|
||||
returns the output iterator instead of a count. Thanks, Paul!
|
||||
- Added another fix by Paul Harris to _M_get_j_max, which would cause
|
||||
a dimensional overflow for trees with depths >= K. Thanks (again) Paul!
|
||||
- Made some improvements to the autotools files.
|
||||
|
||||
2004-05-11 Martin F. Krafft (libkdtree@pobox.madduck.net)
|
||||
|
||||
- Fixed CFlags and Libs entries in pkgconfig file.
|
||||
|
||||
2004-05-11 Martin F. Krafft (libkdtree@pobox.madduck.net)
|
||||
|
||||
- Initial release.
|
||||
|
||||
|
||||
COPYRIGHT --
|
||||
libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net> and
|
||||
Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> and distributed under the
|
||||
terms of the Artistic License 2.0. See the ./COPYING file in the source tree
|
||||
root for more information.
|
||||
|
||||
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
10
src/3rdParty/libkdtree/README.md
vendored
10
src/3rdParty/libkdtree/README.md
vendored
@@ -24,12 +24,12 @@ Please leave bugreports on Github Issues page <https://github.com/nvmd/libkdtree
|
||||
Historical background
|
||||
---------------------
|
||||
|
||||
In the past, this library was available from [http://libkdtree.alioth.debian.org/](https://web.archive.org/web/20180422154001/http://libkdtree.alioth.debian.org/).
|
||||
This page seems to be gone now, available only via [WebArchive](https://web.archive.org/web/20180422154001/http://libkdtree.alioth.debian.org/).
|
||||
In the past, this library was available from <http://libkdtree.alioth.debian.org/>.
|
||||
This page seems to be gone now, available only via WebArchive.
|
||||
This is a mirror and a fork of that original repository, created in
|
||||
2011 and maintained ever since.
|
||||
|
||||
Notes of the original author are preserved below.
|
||||
Notes of the original author a preserved below.
|
||||
|
||||
Installation
|
||||
------------
|
||||
@@ -114,8 +114,8 @@ without the help of a number of people. Foremost, I would like to thank the
|
||||
folks from the #c++ channel on Freenode, specifically (in no particular order)
|
||||
orbitz, quix, Erwin, pwned, wcstok, dasOp, Chaku, Adrinael, The_Vulture, and
|
||||
LIM2 (if I left anyone out, let me know). Finally, I thank the Artificial
|
||||
Intelligence Laboratory of the University of Zurich, Dr. Peter Eggenberger, and
|
||||
Gabriel Gómez for giving me the opportunity to write this stuff.
|
||||
Intelligence Laboratory of the University of Zurich, Dr. Peter Eggenberger and
|
||||
Gabriel Gómez for giving me the opportunity to write this stuff.
|
||||
|
||||
Since libkdtree++ makes an effort to stay as close as possible to the feel of
|
||||
a STL container, concepts and inspiration was gained from the SGI C++
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
add_executable (test_hayne test_hayne.cpp)
|
||||
add_executable (test_kdtree test_kdtree.cpp)
|
||||
add_executable (test_find_within_range test_find_within_range.cpp)
|
||||
@@ -1,108 +0,0 @@
|
||||
// Thanks to James Remillard
|
||||
//
|
||||
#include <cstdio>
|
||||
#include <kdtree++/kdtree.hpp>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct kdtreeNode
|
||||
{
|
||||
typedef double value_type;
|
||||
|
||||
double xyz[3];
|
||||
size_t index;
|
||||
|
||||
value_type operator[](size_t n) const
|
||||
{
|
||||
return xyz[n];
|
||||
}
|
||||
|
||||
double distance( const kdtreeNode &node)
|
||||
{
|
||||
double x = xyz[0] - node.xyz[0];
|
||||
double y = xyz[1] - node.xyz[1];
|
||||
double z = xyz[2] - node.xyz[2];
|
||||
|
||||
// this is not correct return sqrt( x*x+y*y+z*z);
|
||||
|
||||
// this is what kdtree checks with find_within_range()
|
||||
// the "manhattan distance" from the search point.
|
||||
// effectively, distance is the maximum distance in any one dimension.
|
||||
return max(fabs(x),max(fabs(y),fabs(z)));
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
vector<kdtreeNode> pts;
|
||||
|
||||
typedef KDTree::KDTree<3,kdtreeNode> treeType;
|
||||
|
||||
treeType tree;
|
||||
|
||||
// make random 3d points
|
||||
for ( size_t n = 0; n < 10000; ++n)
|
||||
{
|
||||
kdtreeNode node;
|
||||
node.xyz[0] = double(rand())/RAND_MAX;
|
||||
node.xyz[1] = double(rand())/RAND_MAX;
|
||||
node.xyz[2] = double(rand())/RAND_MAX;
|
||||
node.index = n;
|
||||
|
||||
tree.insert( node);
|
||||
pts.push_back( node);
|
||||
}
|
||||
|
||||
for (size_t r = 0; r < 1000; ++r)
|
||||
{
|
||||
kdtreeNode refNode;
|
||||
refNode.xyz[0] = double(rand())/RAND_MAX;
|
||||
refNode.xyz[1] = double(rand())/RAND_MAX;
|
||||
refNode.xyz[2] = double(rand())/RAND_MAX;
|
||||
|
||||
double limit = double(rand())/RAND_MAX;
|
||||
|
||||
// find the correct return list by checking every single point
|
||||
set<size_t> correctCloseList;
|
||||
|
||||
for ( size_t i= 0; i < pts.size(); ++i)
|
||||
{
|
||||
double dist = refNode.distance( pts[i]);
|
||||
if ( dist < limit)
|
||||
correctCloseList.insert( i );
|
||||
}
|
||||
|
||||
// now do the same with the kdtree.
|
||||
vector<kdtreeNode> howClose;
|
||||
tree.find_within_range(refNode,limit,back_insert_iterator<vector<kdtreeNode> >(howClose));
|
||||
|
||||
// make sure no extra points are returned, and the return has no missing points.
|
||||
for ( size_t i = 0; i < howClose.size(); ++i)
|
||||
{
|
||||
set<size_t>::iterator hit = correctCloseList.find( howClose[i].index);
|
||||
|
||||
if ( hit != correctCloseList.end())
|
||||
{
|
||||
correctCloseList.erase(hit);
|
||||
}
|
||||
else
|
||||
{
|
||||
// point that is too far away - fail!
|
||||
assert(false);
|
||||
printf("fail, extra points.\n");
|
||||
}
|
||||
}
|
||||
|
||||
// fail, not all of the close enough points returned.
|
||||
assert( correctCloseList.size() == 0);
|
||||
if ( correctCloseList.size() > 0)
|
||||
{
|
||||
printf("fail, missing points.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
116
src/3rdParty/libkdtree/examples/test_hayne.cpp
vendored
116
src/3rdParty/libkdtree/examples/test_hayne.cpp
vendored
@@ -1,116 +0,0 @@
|
||||
#define KDTREE_SIZE_T unsigned int
|
||||
#include <kdtree++/kdtree.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct duplet
|
||||
{
|
||||
typedef int value_type;
|
||||
|
||||
inline value_type operator[](int const N) const { return d[N]; }
|
||||
|
||||
inline bool operator==(duplet const& other) const
|
||||
{
|
||||
return this->d[0] == other.d[0] && this->d[1] == other.d[1];
|
||||
}
|
||||
|
||||
inline bool operator!=(duplet const& other) const
|
||||
{
|
||||
return this->d[0] != other.d[0] || this->d[1] != other.d[1];
|
||||
}
|
||||
|
||||
friend ostream & operator<<(ostream & o, duplet const& d)
|
||||
{
|
||||
return o << "(" << d[0] << "," << d[1] << ")";
|
||||
}
|
||||
|
||||
value_type d[2];
|
||||
};
|
||||
|
||||
typedef KDTree::KDTree<2, duplet, std::pointer_to_binary_function<duplet,int,double> > duplet_tree_type;
|
||||
|
||||
inline double return_dup( duplet d, int k ) { return d[k]; }
|
||||
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
duplet_tree_type dupl_tree_test(std::ptr_fun(return_dup));
|
||||
std::vector<duplet> vDuplets;
|
||||
|
||||
//srand(time(0));
|
||||
int randy1 = 0;
|
||||
int randy2 = 0;
|
||||
for (int i=0; i<700; i++)
|
||||
{
|
||||
//create coordinate for new duplet
|
||||
randy1+=2;
|
||||
randy1=randy1%255;
|
||||
randy2+=3;
|
||||
randy2=randy2%255;
|
||||
//randy1 = rand() % 255;
|
||||
//randy2 = rand() % 255;
|
||||
|
||||
//new duplet
|
||||
duplet super_dupre = { {randy1, randy2} };
|
||||
|
||||
//check if duplet with same coordinate already in vector/tree. If not: insert in vector and tree
|
||||
duplet_tree_type::iterator pItr = dupl_tree_test.find_nearest(super_dupre,std::numeric_limits<double>::max()).first;
|
||||
if (*pItr!=super_dupre)
|
||||
{
|
||||
dupl_tree_test.insert(super_dupre);
|
||||
vDuplets.push_back(super_dupre);
|
||||
}
|
||||
}
|
||||
|
||||
dupl_tree_test.optimise();
|
||||
|
||||
size_t elements;
|
||||
|
||||
while (vDuplets.size() > 0) //delete all duplets from tree which are in the vector
|
||||
{
|
||||
elements = vDuplets.size();
|
||||
|
||||
duplet element_to_erase = vDuplets.back();
|
||||
vDuplets.pop_back();
|
||||
|
||||
if (vDuplets.size() == 147)
|
||||
cout << "THIS IS THE BUG TRIGGER" << endl;
|
||||
|
||||
cout << vDuplets.size() << " : Deleting " << element_to_erase << endl;
|
||||
|
||||
assert( find(dupl_tree_test.begin(),dupl_tree_test.end(), element_to_erase) != dupl_tree_test.end() );
|
||||
assert(dupl_tree_test.find(element_to_erase) != dupl_tree_test.end());
|
||||
|
||||
duplet_tree_type::iterator will = dupl_tree_test.find(element_to_erase);
|
||||
duplet_tree_type::iterator should = dupl_tree_test.find_exact(element_to_erase);
|
||||
|
||||
cout << " tree will delete: " << *will << endl;
|
||||
cout << " tree should delete: " << *should << endl;
|
||||
|
||||
assert(*will == *should);
|
||||
|
||||
dupl_tree_test.erase(element_to_erase); //erase() : will probably erase wrong element sooner or later
|
||||
//dupl_tree_test.erase_exact(element_to_erase); --> this works
|
||||
|
||||
// now check that it cannot find the element UNLESS there is another one with the identical location in the list...
|
||||
if (find(vDuplets.begin(),vDuplets.end(),element_to_erase) == vDuplets.end())
|
||||
{
|
||||
duplet_tree_type::iterator not_there = dupl_tree_test.find(element_to_erase);
|
||||
if (not_there != dupl_tree_test.end())
|
||||
{
|
||||
cout << "SHOULD NOT HAVE FOUND THIS: " << *not_there << endl;
|
||||
assert(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << " find() double-check passed." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
424
src/3rdParty/libkdtree/examples/test_kdtree.cpp
vendored
424
src/3rdParty/libkdtree/examples/test_kdtree.cpp
vendored
@@ -1,424 +0,0 @@
|
||||
#define KDTREE_DEFINE_OSTREAM_OPERATORS
|
||||
|
||||
// Make SURE all our asserts() are checked
|
||||
#undef NDEBUG
|
||||
|
||||
#include <kdtree++/kdtree.hpp>
|
||||
|
||||
#include <deque>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <functional>
|
||||
#include <set>
|
||||
|
||||
// used to ensure all triplets that are accessed via the operator<< are initialised.
|
||||
std::set<const void*> registered;
|
||||
|
||||
struct triplet
|
||||
{
|
||||
typedef double value_type;
|
||||
|
||||
triplet(value_type a, value_type b, value_type c)
|
||||
{
|
||||
d[0] = a;
|
||||
d[1] = b;
|
||||
d[2] = c;
|
||||
bool reg_ok = (registered.find(this) == registered.end());
|
||||
assert(reg_ok);
|
||||
bool reg_inserted_ok = registered.insert(this).second;
|
||||
assert(reg_inserted_ok);
|
||||
}
|
||||
|
||||
triplet(const triplet & x)
|
||||
{
|
||||
d[0] = x.d[0];
|
||||
d[1] = x.d[1];
|
||||
d[2] = x.d[2];
|
||||
bool reg_ok = (registered.find(this) == registered.end());
|
||||
assert(reg_ok);
|
||||
bool reg_inserted_ok = registered.insert(this).second;
|
||||
assert(reg_inserted_ok);
|
||||
}
|
||||
|
||||
~triplet()
|
||||
{
|
||||
bool unreg_ok = (registered.find(this) != registered.end());
|
||||
assert(unreg_ok);
|
||||
registered.erase(this);
|
||||
}
|
||||
|
||||
double distance_to(triplet const& x) const
|
||||
{
|
||||
double dist = 0;
|
||||
for (int i = 0; i != 3; ++i)
|
||||
dist += (d[i]-x.d[i])*(d[i]-x.d[i]);
|
||||
return std::sqrt(dist);
|
||||
}
|
||||
|
||||
inline value_type operator[](size_t const N) const { return d[N]; }
|
||||
|
||||
value_type d[3];
|
||||
};
|
||||
|
||||
|
||||
|
||||
// same as triplet, except with the values reversed.
|
||||
struct alternate_triplet
|
||||
{
|
||||
typedef double value_type;
|
||||
|
||||
alternate_triplet(const triplet & x)
|
||||
{
|
||||
d[0] = x.d[2];
|
||||
d[1] = x.d[1];
|
||||
d[2] = x.d[0];
|
||||
}
|
||||
|
||||
inline value_type operator[](size_t const N) const { return d[2-N]; }
|
||||
|
||||
value_type d[3];
|
||||
};
|
||||
|
||||
inline bool operator==(triplet const& A, triplet const& B) {
|
||||
return A.d[0] == B.d[0] && A.d[1] == B.d[1] && A.d[2] == B.d[2];
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, triplet const& T)
|
||||
{
|
||||
assert(registered.find(&T) != registered.end());
|
||||
return out << '(' << T.d[0] << ',' << T.d[1] << ',' << T.d[2] << ')';
|
||||
}
|
||||
|
||||
inline double tac( triplet t, size_t k ) { return t[k]; }
|
||||
|
||||
// use tac as a class instead of a function,
|
||||
// can access more than one type with just 1 definition.
|
||||
struct alternate_tac
|
||||
{
|
||||
typedef double result_type;
|
||||
double operator()( triplet const& t, size_t k ) const { return t[k]; }
|
||||
double operator()( alternate_triplet const& t, size_t k ) const { return t[k]; }
|
||||
};
|
||||
|
||||
|
||||
typedef KDTree::KDTree<3, triplet, std::pointer_to_binary_function<triplet,size_t,double> > tree_type;
|
||||
|
||||
struct Predicate
|
||||
{
|
||||
bool operator()( triplet const& t ) const
|
||||
{
|
||||
return t[0] > 3; // anything, we are currently testing that it compiles.
|
||||
}
|
||||
};
|
||||
|
||||
// never finds anything
|
||||
struct FalsePredicate
|
||||
{
|
||||
bool operator()( triplet const& t ) const { return false; }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// check that it'll find nodes exactly MAX away
|
||||
{
|
||||
tree_type exact_dist(std::ptr_fun(tac));
|
||||
triplet c0(5, 4, 0);
|
||||
exact_dist.insert(c0);
|
||||
triplet target(7,4,0);
|
||||
|
||||
std::pair<tree_type::const_iterator,double> found = exact_dist.find_nearest(target,2);
|
||||
assert(found.first != exact_dist.end());
|
||||
assert(found.second == 2);
|
||||
std::cout << "Test find_nearest(), found at exact distance away from " << target << ", found " << *found.first << std::endl;
|
||||
}
|
||||
|
||||
// do the same test, except use alternate_triplet as the search key
|
||||
{
|
||||
// NOTE: stores triplet, but we search with alternate_triplet
|
||||
typedef KDTree::KDTree<3, triplet, alternate_tac> alt_tree;
|
||||
|
||||
triplet actual_target(7,0,0);
|
||||
|
||||
alt_tree tree;
|
||||
tree.insert( triplet(0, 0, 7) );
|
||||
tree.insert( triplet(0, 0, 7) );
|
||||
tree.insert( triplet(0, 0, 7) );
|
||||
tree.insert( triplet(3, 0, 0) );
|
||||
tree.insert( actual_target );
|
||||
tree.optimise();
|
||||
|
||||
alternate_triplet target( actual_target );
|
||||
|
||||
std::pair<alt_tree::const_iterator,double> found = tree.find_nearest(target);
|
||||
assert(found.first != tree.end());
|
||||
std::cout << "Test with alternate search type, found: " << *found.first << ", wanted " << actual_target << std::endl;
|
||||
assert(found.second == 0);
|
||||
assert(*found.first == actual_target);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
tree_type exact_dist(std::ptr_fun(tac));
|
||||
triplet c0(5, 2, 0);
|
||||
exact_dist.insert(c0);
|
||||
triplet target(7,4,0);
|
||||
|
||||
// call find_nearest without a range value - it found a compile error earlier.
|
||||
std::pair<tree_type::const_iterator,double> found = exact_dist.find_nearest(target);
|
||||
assert(found.first != exact_dist.end());
|
||||
std::cout << "Test find_nearest(), found at exact distance away from " << target << ", found " << *found.first << " @ " << found.second << " should be " << std::sqrt(8) << std::endl;
|
||||
assert(found.second == std::sqrt(8));
|
||||
}
|
||||
|
||||
{
|
||||
tree_type exact_dist(std::ptr_fun(tac));
|
||||
triplet c0(5, 2, 0);
|
||||
exact_dist.insert(c0);
|
||||
triplet target(7,4,0);
|
||||
|
||||
std::pair<tree_type::const_iterator,double> found = exact_dist.find_nearest(target,std::sqrt(8));
|
||||
assert(found.first != exact_dist.end());
|
||||
std::cout << "Test find_nearest(), found at exact distance away from " << target << ", found " << *found.first << " @ " << found.second << " should be " << std::sqrt(8) << std::endl;
|
||||
assert(found.second == std::sqrt(8));
|
||||
}
|
||||
|
||||
tree_type src(std::ptr_fun(tac));
|
||||
|
||||
triplet c0(5, 4, 0); src.insert(c0);
|
||||
triplet c1(4, 2, 1); src.insert(c1);
|
||||
triplet c2(7, 6, 9); src.insert(c2);
|
||||
triplet c3(2, 2, 1); src.insert(c3);
|
||||
triplet c4(8, 0, 5); src.insert(c4);
|
||||
triplet c5(5, 7, 0); src.insert(c5);
|
||||
triplet c6(3, 3, 8); src.insert(c6);
|
||||
triplet c7(9, 7, 3); src.insert(c7);
|
||||
triplet c8(2, 2, 6); src.insert(c8);
|
||||
triplet c9(2, 0, 6); src.insert(c9);
|
||||
|
||||
std::cout << src << std::endl;
|
||||
|
||||
src.erase(c0);
|
||||
src.erase(c1);
|
||||
src.erase(c3);
|
||||
src.erase(c5);
|
||||
|
||||
src.optimise();
|
||||
|
||||
|
||||
// test the efficient_replace_and_optimise()
|
||||
tree_type eff_repl = src;
|
||||
{
|
||||
std::vector<triplet> vec;
|
||||
// erased above as part of test vec.push_back(triplet(5, 4, 0));
|
||||
// erased above as part of test vec.push_back(triplet(4, 2, 1));
|
||||
vec.push_back(triplet(7, 6, 9));
|
||||
// erased above as part of test vec.push_back(triplet(2, 2, 1));
|
||||
vec.push_back(triplet(8, 0, 5));
|
||||
// erased above as part of test vec.push_back(triplet(5, 7, 0));
|
||||
vec.push_back(triplet(3, 3, 8));
|
||||
vec.push_back(triplet(9, 7, 3));
|
||||
vec.push_back(triplet(2, 2, 6));
|
||||
vec.push_back(triplet(2, 0, 6));
|
||||
|
||||
eff_repl.clear();
|
||||
eff_repl.efficient_replace_and_optimise(vec);
|
||||
}
|
||||
|
||||
|
||||
std::cout << std::endl << src << std::endl;
|
||||
|
||||
tree_type copied(src);
|
||||
std::cout << copied << std::endl;
|
||||
tree_type assigned = src;
|
||||
std::cout << assigned << std::endl;
|
||||
|
||||
for (int loop = 0; loop != 4; ++loop)
|
||||
{
|
||||
tree_type * target;
|
||||
switch (loop)
|
||||
{
|
||||
case 0: std::cout << "Testing plain construction" << std::endl;
|
||||
target = &src;
|
||||
break;
|
||||
|
||||
case 1: std::cout << "Testing copy-construction" << std::endl;
|
||||
target = &copied;
|
||||
break;
|
||||
|
||||
case 2: std::cout << "Testing assign-construction" << std::endl;
|
||||
target = &assigned;
|
||||
break;
|
||||
|
||||
default:
|
||||
case 4: std::cout << "Testing efficient-replace-and-optimise" << std::endl;
|
||||
target = &eff_repl;
|
||||
break;
|
||||
}
|
||||
tree_type & t = *target;
|
||||
|
||||
int i=0;
|
||||
for (tree_type::const_iterator iter=t.begin(); iter!=t.end(); ++iter, ++i);
|
||||
std::cout << "iterator walked through " << i << " nodes in total" << std::endl;
|
||||
if (i!=6)
|
||||
{
|
||||
std::cerr << "Error: does not tally with the expected number of nodes (6)" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
i=0;
|
||||
for (tree_type::const_reverse_iterator iter=t.rbegin(); iter!=t.rend(); ++iter, ++i);
|
||||
std::cout << "reverse_iterator walked through " << i << " nodes in total" << std::endl;
|
||||
if (i!=6)
|
||||
{
|
||||
std::cerr << "Error: does not tally with the expected number of nodes (6)" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
triplet s(5, 4, 3);
|
||||
std::vector<triplet> v;
|
||||
unsigned int const RANGE = 3;
|
||||
|
||||
size_t count = t.count_within_range(s, RANGE);
|
||||
std::cout << "counted " << count
|
||||
<< " nodes within range " << RANGE << " of " << s << ".\n";
|
||||
t.find_within_range(s, RANGE, std::back_inserter(v));
|
||||
|
||||
std::cout << "found " << v.size() << " nodes within range " << RANGE
|
||||
<< " of " << s << ":\n";
|
||||
std::vector<triplet>::const_iterator ci = v.begin();
|
||||
for (; ci != v.end(); ++ci)
|
||||
std::cout << *ci << " ";
|
||||
std::cout << "\n" << std::endl;
|
||||
|
||||
std::cout << std::endl << t << std::endl;
|
||||
|
||||
// search for all the nodes at exactly 0 dist away
|
||||
for (tree_type::const_iterator target = t.begin(); target != t.end(); ++target)
|
||||
{
|
||||
std::pair<tree_type::const_iterator,double> found = t.find_nearest(*target,0);
|
||||
assert(found.first != t.end());
|
||||
assert(*found.first == *target);
|
||||
std::cout << "Test find_nearest(), found at exact distance away from " << *target << ", found " << *found.first << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
const double small_dist = 0.0001;
|
||||
std::pair<tree_type::const_iterator,double> notfound = t.find_nearest(s,small_dist);
|
||||
std::cout << "Test find_nearest(), nearest to " << s << " within " << small_dist << " should not be found" << std::endl;
|
||||
|
||||
if (notfound.first != t.end())
|
||||
{
|
||||
std::cout << "ERROR found a node at dist " << notfound.second << " : " << *notfound.first << std::endl;
|
||||
std::cout << "Actual distance = " << s.distance_to(*notfound.first) << std::endl;
|
||||
}
|
||||
|
||||
assert(notfound.first == t.end());
|
||||
}
|
||||
|
||||
{
|
||||
std::pair<tree_type::const_iterator,double> nif = t.find_nearest_if(s,std::numeric_limits<double>::max(),Predicate());
|
||||
std::cout << "Test find_nearest_if(), nearest to " << s << " @ " << nif.second << ": " << *nif.first << std::endl;
|
||||
|
||||
std::pair<tree_type::const_iterator,double> cantfind = t.find_nearest_if(s,std::numeric_limits<double>::max(),FalsePredicate());
|
||||
std::cout << "Test find_nearest_if(), nearest to " << s << " should never be found (predicate too strong)" << std::endl;
|
||||
assert(cantfind.first == t.end());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
std::pair<tree_type::const_iterator,double> found = t.find_nearest(s,std::numeric_limits<double>::max());
|
||||
std::cout << "Nearest to " << s << " @ " << found.second << " " << *found.first << std::endl;
|
||||
std::cout << "Should be " << found.first->distance_to(s) << std::endl;
|
||||
// NOTE: the assert does not check for an exact match, as it is not exact when -O2 or -O3 is
|
||||
// switched on. Some sort of optimisation makes the math inexact.
|
||||
assert( fabs(found.second - found.first->distance_to(s)) < std::numeric_limits<double>::epsilon() );
|
||||
}
|
||||
|
||||
{
|
||||
triplet s2(10, 10, 2);
|
||||
std::pair<tree_type::const_iterator,double> found = t.find_nearest(s2,std::numeric_limits<double>::max());
|
||||
std::cout << "Nearest to " << s2 << " @ " << found.second << " " << *found.first << std::endl;
|
||||
std::cout << "Should be " << found.first->distance_to(s2) << std::endl;
|
||||
// NOTE: the assert does not check for an exact match, as it is not exact when -O2 or -O3 is
|
||||
// switched on. Some sort of optimisation makes the math inexact.
|
||||
assert( fabs(found.second - found.first->distance_to(s2)) < std::numeric_limits<double>::epsilon() );
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << t << std::endl;
|
||||
|
||||
// Testing iterators
|
||||
{
|
||||
std::cout << "Testing iterators" << std::endl;
|
||||
|
||||
t.erase(c2);
|
||||
t.erase(c4);
|
||||
t.erase(c6);
|
||||
t.erase(c7);
|
||||
t.erase(c8);
|
||||
// t.erase(c9);
|
||||
|
||||
std::cout << std::endl << t << std::endl;
|
||||
|
||||
std::cout << "Forward iterator test..." << std::endl;
|
||||
std::vector<triplet> forwards;
|
||||
for (tree_type::iterator i = t.begin(); i != t.end(); ++i)
|
||||
{ std::cout << *i << " " << std::flush; forwards.push_back(*i); }
|
||||
std::cout << std::endl;
|
||||
std::cout << "Reverse iterator test..." << std::endl;
|
||||
std::vector<triplet> backwards;
|
||||
for (tree_type::reverse_iterator i = t.rbegin(); i != t.rend(); ++i)
|
||||
{ std::cout << *i << " " << std::flush; backwards.push_back(*i); }
|
||||
std::cout << std::endl;
|
||||
std::reverse(backwards.begin(),backwards.end());
|
||||
assert(backwards == forwards);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Walter reported that the find_within_range() wasn't giving results that were within
|
||||
// the specified range... this is the test.
|
||||
{
|
||||
tree_type tree(std::ptr_fun(tac));
|
||||
tree.insert( triplet(28.771200,16.921600,-2.665970) );
|
||||
tree.insert( triplet(28.553101,18.649700,-2.155560) );
|
||||
tree.insert( triplet(28.107500,20.341400,-1.188940) );
|
||||
tree.optimise();
|
||||
|
||||
std::deque< triplet > vectors;
|
||||
triplet sv(18.892500,20.341400,-1.188940);
|
||||
tree.find_within_range(sv, 10.0f, std::back_inserter(vectors));
|
||||
|
||||
std::cout << std::endl << "Test find_with_range( " << sv << ", 10.0f) found " << vectors.size() << " candidates." << std::endl;
|
||||
|
||||
// double-check the ranges
|
||||
for (std::deque<triplet>::iterator v = vectors.begin(); v != vectors.end(); ++v)
|
||||
{
|
||||
double dist = sv.distance_to(*v);
|
||||
std::cout << " " << *v << " dist=" << dist << std::endl;
|
||||
if (dist > 10.0f)
|
||||
std::cout << " This point is too far! But that is by design, its within a 'box' with a 'radius' of 10, not a sphere with a radius of 10" << std::endl;
|
||||
// Not a valid test, it can be greater than 10 if the point is in the corners of the box.
|
||||
// assert(dist <= 10.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* COPYRIGHT --
|
||||
*
|
||||
* This file is part of libkdtree++, a C++ template KD-Tree sorting container.
|
||||
* libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
|
||||
* and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
|
||||
* terms of the Artistic License 2.0. See the ./COPYING file in the source tree
|
||||
* root for more information.
|
||||
*
|
||||
* THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
4
src/3rdParty/libkdtree/kdtree++/iterator.hpp
vendored
4
src/3rdParty/libkdtree/kdtree++/iterator.hpp
vendored
@@ -54,8 +54,8 @@ namespace KDTree
|
||||
|
||||
inline _Base_iterator(_Base_const_ptr const __N = NULL)
|
||||
: _M_node(__N) {}
|
||||
//inline _Base_iterator(_Base_iterator const& __THAT)
|
||||
// : _M_node(__THAT._M_node) {}
|
||||
inline _Base_iterator(_Base_iterator const& __THAT)
|
||||
: _M_node(__THAT._M_node) {}
|
||||
|
||||
inline void
|
||||
_M_increment()
|
||||
|
||||
5
src/3rdParty/libkdtree/kdtree++/kdtree.hpp
vendored
5
src/3rdParty/libkdtree/kdtree++/kdtree.hpp
vendored
@@ -53,12 +53,12 @@
|
||||
// KDTREE_VERSION % 100 is the patch level
|
||||
// KDTREE_VERSION / 100 % 1000 is the minor version
|
||||
// KDTREE_VERSION / 100000 is the major version
|
||||
#define KDTREE_VERSION 702
|
||||
#define KDTREE_VERSION 704
|
||||
//
|
||||
// KDTREE_LIB_VERSION must be defined to be the same as KDTREE_VERSION
|
||||
// but as a *string* in the form "x_y[_z]" where x is the major version
|
||||
// number, y is the minor version number, and z is the patch level if not 0.
|
||||
#define KDTREE_LIB_VERSION "0_7_2"
|
||||
#define KDTREE_LIB_VERSION "0_7_4"
|
||||
|
||||
|
||||
#include <vector>
|
||||
@@ -1214,7 +1214,6 @@ protected:
|
||||
o << "dimensions: " << __K << std::endl;
|
||||
|
||||
typedef KDTree<__K, _Val, _Acc, _Dist, _Cmp, _Alloc> _Tree;
|
||||
typedef typename _Tree::_Link_type _Link_type;
|
||||
|
||||
std::stack<_Link_const_type> s;
|
||||
s.push(tree._M_get_root());
|
||||
|
||||
2
src/3rdParty/libkdtree/kdtree++/region.hpp
vendored
2
src/3rdParty/libkdtree/kdtree++/region.hpp
vendored
@@ -27,7 +27,7 @@ namespace KDTree
|
||||
typedef std::pair<_Region,_SubVal> _CenterPt;
|
||||
|
||||
_Region(_Acc const& __acc=_Acc(), const _Cmp& __cmp=_Cmp())
|
||||
: _M_cmp(__cmp), _M_acc(__acc) {}
|
||||
: _M_acc(__acc), _M_cmp(__cmp) {}
|
||||
|
||||
template <typename Val>
|
||||
_Region(Val const& __V,
|
||||
|
||||
@@ -10,7 +10,7 @@ include_directories (${CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||
# Build the _kdtree python module
|
||||
set_source_files_properties (py-kdtree.i PROPERTIES CPLUSPLUS ON)
|
||||
swig_add_module (kdtree python py-kdtree.i)
|
||||
swig_link_libraries (kdtree ${Python3_LIBRARIES})
|
||||
swig_link_libraries (kdtree ${PYTHON_LIBRARIES})
|
||||
|
||||
# Copy the test file into the build dir
|
||||
install (FILES py-kdtree_test.py DESTINATION ${CMAKE_INSTALL_PREFIX}/python)
|
||||
|
||||
73
src/3rdParty/lru-cache/CMakeLists.txt
vendored
Normal file
73
src/3rdParty/lru-cache/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
###########################################################
|
||||
## CMAKE SETUP
|
||||
###########################################################
|
||||
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
project(lru-cache)
|
||||
|
||||
add_compile_options(-g)
|
||||
|
||||
########################################
|
||||
# C++ VERSIONING
|
||||
########################################
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
# check_cxx_compiler_flag("-std=c++14" COMPILER_SUPPORTS_CXX_14)
|
||||
# check_cxx_compiler_flag("-std=c++1z" COMPILER_SUPPORTS_CXX_1z)
|
||||
# check_cxx_compiler_flag("-std=c++17" COMPILER_SUPPORTS_CXX_17)
|
||||
|
||||
# if (COMPILER_SUPPORTS_CXX_1z)
|
||||
# message(STATUS "Compiling with C++1z")
|
||||
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1z")
|
||||
# elseif (COMPILER_SUPPORTS_CXX_14)
|
||||
# message(STATUS "Compiling with C++14")
|
||||
# set(CMAKE_CXX_STANDARD 14)
|
||||
# elseif (COMPILER_SUPPORTS_CXX_17)
|
||||
# message(STATUS "Compiling with C++17")
|
||||
# set(CMAKE_CXX_STANDARD 17)
|
||||
# else()
|
||||
# message(FATAL_ERROR "Please install a modern C++ compiler, they are not expensive.")
|
||||
# endif()
|
||||
|
||||
###########################################################
|
||||
## DEPENDENCIES
|
||||
###########################################################
|
||||
|
||||
set(CMAKE_MODULE_PATH
|
||||
${CMAKE_MODULE_PATH}
|
||||
"${CMAKE_SOURCE_DIR}/cmake/Modules/"
|
||||
)
|
||||
|
||||
###########################################################
|
||||
## INCLUDES
|
||||
###########################################################
|
||||
|
||||
# Need this top-level include for "tests/"
|
||||
# include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
###########################################################
|
||||
## EXAMPLES
|
||||
###########################################################
|
||||
|
||||
# add_subdirectory(examples)
|
||||
|
||||
########################################
|
||||
# TESTS
|
||||
########################################
|
||||
|
||||
# option(BUILD_LRU_CACHE_TESTS "Enable tests" OFF)
|
||||
|
||||
# if(BUILD_LRU_CACHE_TESTS)
|
||||
# message(STATUS "Enabling tests ...")
|
||||
# enable_testing()
|
||||
# add_subdirectory(tests)
|
||||
# else()
|
||||
# message(STATUS "Disabling tests ...")
|
||||
# endif()
|
||||
|
||||
file (GLOB LRU_HEADERS include/*.hpp)
|
||||
file (GLOB LRU_INTERNAL_HEADERS include/*.hpp)
|
||||
install (FILES ${LRU_HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
|
||||
install (FILES ${LRU_INTERNAL_HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/internal)
|
||||
19
src/3rdParty/lru-cache/LICENSE
vendored
Normal file
19
src/3rdParty/lru-cache/LICENSE
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2016 Peter Goldsborough
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
304
src/3rdParty/lru-cache/README.md
vendored
Normal file
304
src/3rdParty/lru-cache/README.md
vendored
Normal file
File diff suppressed because one or more lines are too long
3
src/3rdParty/lru-cache/cpplint.cfg
vendored
Normal file
3
src/3rdParty/lru-cache/cpplint.cfg
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# cpplint configuration
|
||||
|
||||
filter=-build/c++11,-whitespace/parens,-runtime/references,-whitespace/operators
|
||||
2310
src/3rdParty/lru-cache/docs/Doxyfile
vendored
Normal file
2310
src/3rdParty/lru-cache/docs/Doxyfile
vendored
Normal file
File diff suppressed because it is too large
Load Diff
16
src/3rdParty/lru-cache/examples/CMakeLists.txt
vendored
Normal file
16
src/3rdParty/lru-cache/examples/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
###########################################################
|
||||
## BINARIES
|
||||
###########################################################
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/examples)
|
||||
|
||||
########################################
|
||||
# TARGETS
|
||||
########################################
|
||||
|
||||
add_executable(fibonacci-basic fibonacci-basic.cpp)
|
||||
add_executable(fibonacci-timed fibonacci-timed.cpp)
|
||||
add_executable(statistics statistics.cpp)
|
||||
add_executable(callbacks callbacks.cpp)
|
||||
add_executable(lowercase lowercase.cpp)
|
||||
add_executable(wrap wrap.cpp)
|
||||
76
src/3rdParty/lru-cache/examples/callbacks.cpp
vendored
Normal file
76
src/3rdParty/lru-cache/examples/callbacks.cpp
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "lru/lru.hpp"
|
||||
|
||||
using Cache = LRU::Cache<std::uint64_t, std::uint64_t>;
|
||||
|
||||
std::uint64_t fibonacci(std::uint64_t n, Cache& cache) {
|
||||
if (n < 2) return 1;
|
||||
|
||||
// We std::uint64_ternally keep track of the last accessed key, meaning a
|
||||
// `contains(key)` + `lookup(key)` sequence will involve only a single hash
|
||||
// table lookup.
|
||||
if (cache.contains(n)) return cache[n];
|
||||
|
||||
auto value = fibonacci(n - 1, cache) + fibonacci(n - 2, cache);
|
||||
|
||||
// Caches are 100% move-aware and we have implemented
|
||||
// `unordered_map` style emplacement and insertion.
|
||||
cache.emplace(n, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
std::uint64_t fibonacci(std::uint64_t n) {
|
||||
// Use a capacity of 100 (after 100 insertions, the next insertion will evict
|
||||
// the least-recently inserted element). The default capacity is 128. Note
|
||||
// that for fibonacci, a capacity of 2 is sufficient (and ideal).
|
||||
Cache cache(100);
|
||||
|
||||
// clang-format off
|
||||
cache.hit_callback([](auto& key, auto& value) {
|
||||
std::clog << "Hit for entry ("
|
||||
<< key << ", " << value << ")"
|
||||
<< std::endl;
|
||||
});
|
||||
|
||||
cache.miss_callback([](auto& key) {
|
||||
std::clog << "Miss for " << key<< std::endl;
|
||||
});
|
||||
|
||||
cache.access_callback([](auto& key, bool was_hit) {
|
||||
std::clog << "Access for " << key
|
||||
<< " was a " << (was_hit ? "hit" : "miss")
|
||||
<< std::endl;
|
||||
});
|
||||
// clang-format on
|
||||
|
||||
auto value = fibonacci(n, cache);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
auto main() -> int {
|
||||
std::cout << fibonacci(10) << std::endl;
|
||||
}
|
||||
55
src/3rdParty/lru-cache/examples/fibonacci-basic.cpp
vendored
Normal file
55
src/3rdParty/lru-cache/examples/fibonacci-basic.cpp
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "lru/lru.hpp"
|
||||
|
||||
using Cache = LRU::Cache<int, int>;
|
||||
|
||||
int fibonacci(int n, Cache& cache) {
|
||||
if (n < 2) return 1;
|
||||
|
||||
// We internally keep track of the last accessed key, meaning a
|
||||
// `contains(key)` + `lookup(key)` sequence will involve only a single hash
|
||||
// table lookup.
|
||||
if (cache.contains(n)) return cache[n];
|
||||
|
||||
auto value = fibonacci(n - 1, cache) + fibonacci(n - 2, cache);
|
||||
|
||||
// Caches are 100% move-aware and we have implemented
|
||||
// `unordered_map` style emplacement and insertion.
|
||||
cache.emplace(n, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int fibonacci(int n) {
|
||||
// Use a capacity of 100 (after 100 insertions, the next insertion will evict
|
||||
// the least-recently accessed element). The default capacity is 128. Note
|
||||
// that for fibonacci, a capacity of 2 is sufficient (and ideal).
|
||||
Cache cache(100);
|
||||
return fibonacci(n, cache);
|
||||
}
|
||||
|
||||
auto main() -> int {
|
||||
std::cout << fibonacci(32) << std::endl;
|
||||
}
|
||||
57
src/3rdParty/lru-cache/examples/fibonacci-timed.cpp
vendored
Normal file
57
src/3rdParty/lru-cache/examples/fibonacci-timed.cpp
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
|
||||
#include "lru/lru.hpp"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
using Cache = LRU::TimedCache<int, int>;
|
||||
|
||||
int fibonacci(int n, Cache& cache) {
|
||||
if (n < 2) return 1;
|
||||
|
||||
// We internally keep track of the last accessed key, meaning a
|
||||
// `contains(key)` + `lookup(key)` sequence will involve only a single hash
|
||||
// table lookup.
|
||||
if (cache.contains(n)) return cache[n];
|
||||
|
||||
auto value = fibonacci(n - 1, cache) + fibonacci(n - 2, cache);
|
||||
|
||||
// Caches are 100% move-aware and we have implemented
|
||||
// `unordered_map` style emplacement and insertion.
|
||||
cache.emplace(n, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int fibonacci(int n) {
|
||||
// Use a time to live of 100ms. This means that 100ms after insertion, a key
|
||||
// will be said to have "expired" and `contains(key)` will return false.
|
||||
Cache cache(100ms);
|
||||
return fibonacci(n, cache);
|
||||
}
|
||||
|
||||
auto main() -> int {
|
||||
std::cout << fibonacci(32) << std::endl;
|
||||
}
|
||||
47
src/3rdParty/lru-cache/examples/lowercase.cpp
vendored
Normal file
47
src/3rdParty/lru-cache/examples/lowercase.cpp
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
|
||||
#include "lru/lowercase.hpp"
|
||||
|
||||
void print(lru::tag::basic_cache) {
|
||||
std::cout << "basic cache" << '\n';
|
||||
}
|
||||
|
||||
void print(lru::tag::timed_cache) {
|
||||
std::cout << "timed cache" << '\n';
|
||||
}
|
||||
|
||||
auto main() -> int {
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
lru::cache<int, int> cache;
|
||||
lru::timed_cache<int, int> timed_cache(100ms);
|
||||
|
||||
print(cache.tag());
|
||||
print(timed_cache.tag());
|
||||
|
||||
lru::cache<int, int>::ordered_const_iterator iterator(cache.begin());
|
||||
|
||||
lru::statistics<int> stats;
|
||||
}
|
||||
76
src/3rdParty/lru-cache/examples/statistics.cpp
vendored
Normal file
76
src/3rdParty/lru-cache/examples/statistics.cpp
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "lru/lru.hpp"
|
||||
|
||||
using Cache = LRU::Cache<std::uint64_t, std::uint64_t>;
|
||||
|
||||
std::uint64_t fibonacci(std::uint64_t n, Cache& cache) {
|
||||
if (n < 2) return 1;
|
||||
|
||||
// We std::uint64_ternally keep track of the last accessed key, meaning a
|
||||
// `contains(key)` + `lookup(key)` sequence will involve only a single hash
|
||||
// table lookup.
|
||||
if (cache.contains(n)) return cache[n];
|
||||
|
||||
auto value = fibonacci(n - 1, cache) + fibonacci(n - 2, cache);
|
||||
|
||||
// Caches are 100% move-aware and we have implemented
|
||||
// `unordered_map` style emplacement and insertion.
|
||||
cache.emplace(n, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
std::uint64_t fibonacci(std::uint64_t n) {
|
||||
// Use a capacity of 100 (after 100 insertions, the next insertion will evict
|
||||
// the least-recently inserted element). The default capacity is 128. Note
|
||||
// that for fibonacci, a capacity of 2 is sufficient (and ideal).
|
||||
Cache cache(100);
|
||||
cache.monitor(2, 3, 4, 5);
|
||||
auto value = fibonacci(n, cache);
|
||||
|
||||
for (auto i : {2, 3, 4, 5}) {
|
||||
auto stats = cache.stats().stats_for(i);
|
||||
// clang-format off
|
||||
std::cout << "Statistics for " << i << ": "
|
||||
<< stats.hits << " hit(s), "
|
||||
<< stats.misses << " miss(es)."
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
// You'll notice we'll always have n - 1 misses, for each time we access
|
||||
// one of the numbers in [0, n] for the first time.
|
||||
std::cout << "Overall: "
|
||||
<< cache.stats().total_hits() << " hit(s), "
|
||||
<< cache.stats().total_misses() << " miss(es)."
|
||||
<< std::endl;
|
||||
// clang-format on
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
auto main() -> int {
|
||||
// The last number that fits into a 64 bit unsigned number
|
||||
std::cout << fibonacci(92) << std::endl;
|
||||
}
|
||||
45
src/3rdParty/lru-cache/examples/wrap.cpp
vendored
Normal file
45
src/3rdParty/lru-cache/examples/wrap.cpp
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include "lru/lru.hpp"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
int f(int x) {
|
||||
std::this_thread::sleep_for(1s);
|
||||
return x;
|
||||
}
|
||||
|
||||
auto main() -> int {
|
||||
// Use a time-to-live of 2 minutes and a
|
||||
// capacity of 128 for an LRU::TimedCache
|
||||
auto wrapped = LRU::timed_wrap(f, 2min, 128);
|
||||
|
||||
std::cout << "Slow the first time ..." << '\n';
|
||||
wrapped(42);
|
||||
|
||||
std::cout << "Fast the second time!" << '\n';
|
||||
wrapped(42);
|
||||
}
|
||||
40
src/3rdParty/lru-cache/include/lru/cache-tags.hpp
vendored
Normal file
40
src/3rdParty/lru-cache/include/lru/cache-tags.hpp
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef LRU_CACHE_TAGS_HPP
|
||||
#define LRU_CACHE_TAGS_HPP
|
||||
|
||||
namespace LRU {
|
||||
namespace Tag {
|
||||
struct BasicCache {};
|
||||
struct TimedCache {};
|
||||
} // namespace Tag
|
||||
|
||||
namespace Lowercase {
|
||||
namespace tag {
|
||||
using basic_cache = ::LRU::Tag::BasicCache;
|
||||
using timed_cache = ::LRU::Tag::TimedCache;
|
||||
} // namespace tag
|
||||
} // namespace Lowercase
|
||||
|
||||
} // namespace LRU
|
||||
|
||||
#endif // LRU_CACHE_TAGS_HPP
|
||||
207
src/3rdParty/lru-cache/include/lru/cache.hpp
vendored
Normal file
207
src/3rdParty/lru-cache/include/lru/cache.hpp
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef LRU_CACHE_HPP
|
||||
#define LRU_CACHE_HPP
|
||||
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <lru/cache-tags.hpp>
|
||||
#include <lru/error.hpp>
|
||||
#include <lru/internal/base-cache.hpp>
|
||||
#include <lru/internal/information.hpp>
|
||||
#include <lru/internal/last-accessed.hpp>
|
||||
|
||||
namespace LRU {
|
||||
namespace Internal {
|
||||
template <typename Key,
|
||||
typename Value,
|
||||
typename HashFunction,
|
||||
typename KeyEqual>
|
||||
using UntimedCacheBase = Internal::BaseCache<Key,
|
||||
Value,
|
||||
Internal::Information,
|
||||
HashFunction,
|
||||
KeyEqual,
|
||||
Tag::BasicCache>;
|
||||
} // namespace Internal
|
||||
|
||||
/// A basic LRU cache implementation.
|
||||
///
|
||||
/// An LRU cache is a fixed-size cache that remembers the order in which
|
||||
/// elements were inserted into it. When the size of the cache exceeds its
|
||||
/// capacity, the "least-recently-used" (LRU) element is erased. In our
|
||||
/// implementation, usage is defined as insertion, but not lookup. That is,
|
||||
/// looking up an element does not move it to the "front" of the cache (making
|
||||
/// the operation faster). Only insertions (and erasures) can change the order
|
||||
/// of elements. The capacity of the cache can be modified at any time.
|
||||
///
|
||||
/// \see LRU::TimedCache
|
||||
template <typename Key,
|
||||
typename Value,
|
||||
typename HashFunction = std::hash<Key>,
|
||||
typename KeyEqual = std::equal_to<Key>>
|
||||
class Cache
|
||||
: public Internal::UntimedCacheBase<Key, Value, HashFunction, KeyEqual> {
|
||||
private:
|
||||
using super = Internal::UntimedCacheBase<Key, Value, HashFunction, KeyEqual>;
|
||||
using PRIVATE_BASE_CACHE_MEMBERS;
|
||||
|
||||
public:
|
||||
using PUBLIC_BASE_CACHE_MEMBERS;
|
||||
using typename super::size_t;
|
||||
|
||||
/// \copydoc BaseCache::BaseCache(size_t,const HashFunction&,const KeyEqual&)
|
||||
/// \detailss The capacity defaults to an internal constant, currently 128.
|
||||
explicit Cache(size_t capacity = Internal::DEFAULT_CAPACITY,
|
||||
const HashFunction& hash = HashFunction(),
|
||||
const KeyEqual& equal = KeyEqual())
|
||||
: super(capacity, hash, equal) {
|
||||
}
|
||||
|
||||
/// \copydoc BaseCache(size_t,Iterator,Iterator,const HashFunction&,const
|
||||
/// KeyEqual&)
|
||||
template <typename Iterator>
|
||||
Cache(size_t capacity,
|
||||
Iterator begin,
|
||||
Iterator end,
|
||||
const HashFunction& hash = HashFunction(),
|
||||
const KeyEqual& equal = KeyEqual())
|
||||
: super(capacity, begin, end, hash, equal) {
|
||||
}
|
||||
|
||||
/// \copydoc BaseCache(Iterator,Iterator,const HashFunction&,const
|
||||
/// KeyEqual&)
|
||||
template <typename Iterator>
|
||||
Cache(Iterator begin,
|
||||
Iterator end,
|
||||
const HashFunction& hash = HashFunction(),
|
||||
const KeyEqual& equal = KeyEqual())
|
||||
: super(begin, end, hash, equal) {
|
||||
}
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param capacity The capacity of the cache.
|
||||
/// \param range A range to construct the cache with.
|
||||
/// \param hash The hash function to use for the internal map.
|
||||
/// \param key_equal The key equality function to use for the internal map.
|
||||
template <typename Range, typename = Internal::enable_if_range<Range>>
|
||||
Cache(size_t capacity,
|
||||
Range&& range,
|
||||
const HashFunction& hash = HashFunction(),
|
||||
const KeyEqual& equal = KeyEqual())
|
||||
: super(capacity, std::forward<Range>(range), hash, equal) {
|
||||
}
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param range A range to construct the cache with.
|
||||
/// \param hash The hash function to use for the internal map.
|
||||
/// \param key_equal The key equality function to use for the internal map.
|
||||
template <typename Range, typename = Internal::enable_if_range<Range>>
|
||||
explicit Cache(Range&& range,
|
||||
const HashFunction& hash = HashFunction(),
|
||||
const KeyEqual& equal = KeyEqual())
|
||||
: super(std::forward<Range>(range), hash, equal) {
|
||||
}
|
||||
|
||||
/// \copydoc BaseCache(InitializerList,const HashFunction&,const
|
||||
/// KeyEqual&)
|
||||
Cache(InitializerList list,
|
||||
const HashFunction& hash = HashFunction(),
|
||||
const KeyEqual& equal = KeyEqual()) // NOLINT(runtime/explicit)
|
||||
: super(list, hash, equal) {
|
||||
}
|
||||
|
||||
/// \copydoc BaseCache(size_t,InitializerList,const HashFunction&,const
|
||||
/// KeyEqual&)
|
||||
Cache(size_t capacity,
|
||||
InitializerList list,
|
||||
const HashFunction& hash = HashFunction(),
|
||||
const KeyEqual& equal = KeyEqual()) // NOLINT(runtime/explicit)
|
||||
: super(capacity, list, hash, equal) {
|
||||
}
|
||||
|
||||
/// \copydoc BaseCache::find(const Key&)
|
||||
UnorderedIterator find(const Key& key) override {
|
||||
auto iterator = _map.find(key);
|
||||
if (iterator != _map.end()) {
|
||||
_register_hit(key, iterator->second.value);
|
||||
_move_to_front(iterator->second.order);
|
||||
_last_accessed = iterator;
|
||||
} else {
|
||||
_register_miss(key);
|
||||
}
|
||||
|
||||
return {*this, iterator};
|
||||
}
|
||||
|
||||
/// \copydoc BaseCache::find(const Key&) const
|
||||
UnorderedConstIterator find(const Key& key) const override {
|
||||
auto iterator = _map.find(key);
|
||||
if (iterator != _map.end()) {
|
||||
_register_hit(key, iterator->second.value);
|
||||
_move_to_front(iterator->second.order);
|
||||
_last_accessed = iterator;
|
||||
} else {
|
||||
_register_miss(key);
|
||||
}
|
||||
|
||||
return {*this, iterator};
|
||||
}
|
||||
|
||||
/// \returns The most-recently inserted element.
|
||||
const Key& front() const noexcept {
|
||||
if (is_empty()) {
|
||||
throw LRU::Error::EmptyCache("front");
|
||||
} else {
|
||||
// The queue is reversed for natural order of iteration.
|
||||
return _order.back();
|
||||
}
|
||||
}
|
||||
|
||||
/// \returns The least-recently inserted element.
|
||||
const Key& back() const noexcept {
|
||||
if (is_empty()) {
|
||||
throw LRU::Error::EmptyCache("back");
|
||||
} else {
|
||||
// The queue is reversed for natural order of iteration.
|
||||
return _order.front();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
namespace Lowercase {
|
||||
template <typename... Ts>
|
||||
using cache = Cache<Ts...>;
|
||||
} // namespace Lowercase
|
||||
|
||||
} // namespace LRU
|
||||
|
||||
#endif // LRU_CACHE_HPP
|
||||
134
src/3rdParty/lru-cache/include/lru/entry.hpp
vendored
Normal file
134
src/3rdParty/lru-cache/include/lru/entry.hpp
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef LRU_PAIR_HPP
|
||||
#define LRU_PAIR_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace LRU {
|
||||
|
||||
/// A entry of references to the key and value of an entry in a cache.
|
||||
///
|
||||
/// Instances of this class are usually the result of dereferencing an iterator.
|
||||
///
|
||||
/// \tparam Key The key type of the pair.
|
||||
/// \tparam Value The value type of the pair.
|
||||
template <typename Key, typename Value>
|
||||
struct Entry final {
|
||||
using KeyType = Key;
|
||||
using ValueType = Value;
|
||||
using first_type = Key;
|
||||
using second_type = Value;
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param key The key of the entry.
|
||||
/// \param value The value of the entry.
|
||||
Entry(const Key& key, Value& value) : first(key), second(value) {
|
||||
}
|
||||
|
||||
/// Generalized copy constructor.
|
||||
///
|
||||
/// Mainly for conversion from non-const values to const values.
|
||||
///
|
||||
/// \param other The entry to construct from.
|
||||
template <typename AnyKey,
|
||||
typename AnyValue,
|
||||
typename =
|
||||
std::enable_if_t<(std::is_convertible<AnyKey, Key>::value &&
|
||||
std::is_convertible<AnyValue, Value>::value)>>
|
||||
Entry(const Entry<AnyKey, AnyValue>& other)
|
||||
: first(other.first), second(other.second) {
|
||||
}
|
||||
|
||||
/// Compares two entrys for equality.
|
||||
///
|
||||
/// \param first The first entry to compare.
|
||||
/// \param second The second entry to compare.
|
||||
/// \returns True if the firest entry equals the second, else false.
|
||||
template <typename Pair, typename = typename Pair::first_type>
|
||||
friend bool operator==(const Entry& first, const Pair& second) noexcept {
|
||||
return first.first == second.first && first.second == second.second;
|
||||
}
|
||||
|
||||
/// Compares two entrys for equality.
|
||||
///
|
||||
/// \param first The first entry to compare.
|
||||
/// \param second The second entry to compare.
|
||||
/// \returns True if the first entry equals the second, else false.
|
||||
template <typename Pair, typename = typename Pair::first_type>
|
||||
friend bool operator==(const Pair& first, const Entry& second) noexcept {
|
||||
return second == first;
|
||||
}
|
||||
|
||||
/// Compares two entrys for inequality.
|
||||
///
|
||||
/// \param first The first entry to compare.
|
||||
/// \param second The second entry to compare.
|
||||
/// \returns True if the first entry does not equal the second, else false.
|
||||
template <typename Pair, typename = typename Pair::first_type>
|
||||
friend bool operator!=(const Entry& first, const Pair& second) noexcept {
|
||||
return !(first == second);
|
||||
}
|
||||
|
||||
/// Compares two entrys for inequality.
|
||||
///
|
||||
/// \param first The first entry to compare.
|
||||
/// \param second The second entry to compare.fdas
|
||||
/// \returns True if the first entry does not equal the second, else false.
|
||||
template <typename Pair, typename = typename Pair::first_type>
|
||||
friend bool operator!=(const Pair& first, const Entry& second) noexcept {
|
||||
return second != first;
|
||||
}
|
||||
|
||||
/// \returns A `std::pair` instance with the key and value of this entry.
|
||||
operator std::pair<const Key&, Value&>() noexcept {
|
||||
return {first, second};
|
||||
}
|
||||
|
||||
/// \returns The key of the entry (`first`).
|
||||
const Key& key() const noexcept {
|
||||
return first;
|
||||
}
|
||||
|
||||
/// \returns The value of the entry (`second`).
|
||||
Value& value() noexcept {
|
||||
return second;
|
||||
}
|
||||
|
||||
/// \returns The value of the entry (`second`).
|
||||
const Value& value() const noexcept {
|
||||
return second;
|
||||
}
|
||||
|
||||
/// The key of the entry.
|
||||
const Key& first;
|
||||
|
||||
/// The value of the entry.
|
||||
Value& second;
|
||||
};
|
||||
} // namespace LRU
|
||||
|
||||
|
||||
#endif // LRU_PAIR_HPP
|
||||
107
src/3rdParty/lru-cache/include/lru/error.hpp
vendored
Normal file
107
src/3rdParty/lru-cache/include/lru/error.hpp
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef LRU_INTERNAL_ERRORS_HPP
|
||||
#define LRU_INTERNAL_ERRORS_HPP
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace LRU {
|
||||
namespace Error {
|
||||
|
||||
/// Exception thrown when the value of an invalid key was requested.
|
||||
struct KeyNotFound : public std::runtime_error {
|
||||
using super = std::runtime_error;
|
||||
|
||||
KeyNotFound() : super("Failed to find key") {
|
||||
}
|
||||
|
||||
explicit KeyNotFound(const std::string& key)
|
||||
: super("Failed to find key: " + key) {
|
||||
}
|
||||
};
|
||||
|
||||
/// Exception thrown when the value of an expired key was requested.
|
||||
struct KeyExpired : public std::runtime_error {
|
||||
using super = std::runtime_error;
|
||||
|
||||
explicit KeyExpired(const std::string& key)
|
||||
: super("Key found, but expired: " + key) {
|
||||
}
|
||||
|
||||
KeyExpired() : super("Key found, but expired") {
|
||||
}
|
||||
};
|
||||
|
||||
/// Exception thrown when requesting the front or end key of an empty cache.
|
||||
struct EmptyCache : public std::runtime_error {
|
||||
using super = std::runtime_error;
|
||||
explicit EmptyCache(const std::string& what_was_expected)
|
||||
: super("Requested " + what_was_expected + " of empty cache") {
|
||||
}
|
||||
};
|
||||
|
||||
/// Exception thrown when attempting to convert an invalid unordered iterator to
|
||||
/// an ordered iterator.
|
||||
struct InvalidIteratorConversion : public std::runtime_error {
|
||||
using super = std::runtime_error;
|
||||
InvalidIteratorConversion()
|
||||
: super("Cannot convert past-the-end unordered to ordered iterator") {
|
||||
}
|
||||
};
|
||||
|
||||
/// Exception thrown when attempting to erase the past-the-end iterator.
|
||||
struct InvalidIterator : public std::runtime_error {
|
||||
using super = std::runtime_error;
|
||||
InvalidIterator() : super("Past-the-end iterator is invalid here") {
|
||||
}
|
||||
};
|
||||
|
||||
/// Exception thrown when requesting statistics about an unmonitored key.
|
||||
struct UnmonitoredKey : public std::runtime_error {
|
||||
using super = std::runtime_error;
|
||||
UnmonitoredKey() : super("Requested statistics for unmonitored key") {
|
||||
}
|
||||
};
|
||||
|
||||
/// Exception thrown when requesting the statistics object of a cache when none
|
||||
/// was registered.
|
||||
struct NotMonitoring : public std::runtime_error {
|
||||
using super = std::runtime_error;
|
||||
NotMonitoring() : super("Statistics monitoring not enabled for this cache") {
|
||||
}
|
||||
};
|
||||
|
||||
namespace Lowercase {
|
||||
using key_not_found = KeyNotFound;
|
||||
using key_expired = KeyExpired;
|
||||
using empty_cache = EmptyCache;
|
||||
using invalid_iterator_conversion = InvalidIteratorConversion;
|
||||
using invalid_iterator = InvalidIterator;
|
||||
using unmonitored_key = UnmonitoredKey;
|
||||
using not_monitoring = NotMonitoring;
|
||||
} // namespace Lowercase
|
||||
|
||||
} // namespace Error
|
||||
} // namespace LRU
|
||||
|
||||
#endif // LRU_INTERNAL_ERRORS_HPP
|
||||
76
src/3rdParty/lru-cache/include/lru/insertion-result.hpp
vendored
Normal file
76
src/3rdParty/lru-cache/include/lru/insertion-result.hpp
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef LRU_INSERTION_RESULT_HPP
|
||||
#define LRU_INSERTION_RESULT_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace LRU {
|
||||
|
||||
/// The result of an insertion into a cache.
|
||||
///
|
||||
/// This is a semantically nicer alternative to a generic `std::pair`, as is
|
||||
/// returned by `std::unordered_map` or so. It still has the same static
|
||||
/// interface as the `std::pair` (with `first` and `second` members), but adds
|
||||
/// nicer `was_inserted()` and `iterator()` accessors.
|
||||
///
|
||||
/// \tparam Iterator The class of the iterator contained in the result.
|
||||
template <typename Iterator>
|
||||
struct InsertionResult final {
|
||||
using IteratorType = Iterator;
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param result Whether the result was successful.
|
||||
/// \param iterator The iterator pointing to the inserted or updated key.
|
||||
InsertionResult(bool result, Iterator iterator)
|
||||
: first(result), second(iterator) {
|
||||
}
|
||||
|
||||
/// \returns True if the key was newly inserted, false if it was only updated.
|
||||
bool was_inserted() const noexcept {
|
||||
return first;
|
||||
}
|
||||
|
||||
/// \returns The iterator pointing to the inserted or updated key.
|
||||
Iterator iterator() const noexcept {
|
||||
return second;
|
||||
}
|
||||
|
||||
/// \copydoc was_inserted
|
||||
explicit operator bool() const noexcept {
|
||||
return was_inserted();
|
||||
}
|
||||
|
||||
/// Whether the result was successful.
|
||||
bool first;
|
||||
|
||||
/// The iterator pointing to the inserted or updated key.
|
||||
Iterator second;
|
||||
};
|
||||
|
||||
} // namespace LRU
|
||||
|
||||
|
||||
#endif // LRU_INSERTION_RESULT_HPP
|
||||
1588
src/3rdParty/lru-cache/include/lru/internal/base-cache.hpp
vendored
Normal file
1588
src/3rdParty/lru-cache/include/lru/internal/base-cache.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
216
src/3rdParty/lru-cache/include/lru/internal/base-iterator.hpp
vendored
Normal file
216
src/3rdParty/lru-cache/include/lru/internal/base-iterator.hpp
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef LRU_INTERNAL_BASE_ITERATOR_HPP
|
||||
#define LRU_INTERNAL_BASE_ITERATOR_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include <lru/entry.hpp>
|
||||
#include <lru/internal/optional.hpp>
|
||||
|
||||
#define PUBLIC_BASE_ITERATOR_MEMBERS \
|
||||
typename super::Entry; \
|
||||
using typename super::KeyType; \
|
||||
using typename super::ValueType;
|
||||
|
||||
#define PRIVATE_BASE_ITERATOR_MEMBERS \
|
||||
super::_iterator; \
|
||||
using super::_entry; \
|
||||
using super::_cache;
|
||||
|
||||
|
||||
namespace LRU {
|
||||
namespace Internal {
|
||||
|
||||
/// The base class for all (ordered and unordered) iterators.
|
||||
///
|
||||
/// All iterators over our LRU caches store a reference to the cache they point
|
||||
/// into, an underlying iterator they adapt (e.g. a map iterator or list
|
||||
/// iterator) as well as a entry, a reference to which is returned when
|
||||
/// dereferencing the iterator.
|
||||
///
|
||||
/// \tparam IteratorTag A standard iterator category tag.
|
||||
/// \tparam Key The key type over which instances of the iterator iterate.
|
||||
/// \tparam Value The value type over which instances of the iterator iterate.
|
||||
/// \tparam Cache The type of the cache instances of the iterator point into.
|
||||
/// \tparam UnderlyingIterator The underlying iterator class used to implement
|
||||
/// the iterator.
|
||||
template <typename IteratorTag,
|
||||
typename Key,
|
||||
typename Value,
|
||||
typename Cache,
|
||||
typename UnderlyingIterator>
|
||||
class BaseIterator : public std::iterator<IteratorTag, LRU::Entry<Key, Value>> {
|
||||
public:
|
||||
using KeyType = Key;
|
||||
using ValueType =
|
||||
std::conditional_t<std::is_const<Cache>::value, const Value, Value>;
|
||||
using Entry = LRU::Entry<KeyType, ValueType>;
|
||||
|
||||
/// Default constructor.
|
||||
BaseIterator() noexcept : _cache(nullptr) {
|
||||
}
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param cache The cache this iterator points into.
|
||||
/// \param iterator The underlying iterator to adapt.
|
||||
BaseIterator(Cache& cache, const UnderlyingIterator& iterator) noexcept
|
||||
: _iterator(iterator), _cache(&cache) {
|
||||
}
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
/// Differs from the default copy constructor in that it does not copy the
|
||||
/// entry.
|
||||
///
|
||||
/// \param other The base iterator to copy.
|
||||
BaseIterator(const BaseIterator& other) noexcept
|
||||
: _iterator(other._iterator), _cache(other._cache) {
|
||||
// Note: we do not copy the entry, as it would require a new allocation.
|
||||
// Since iterators are often taken by value, this may incur a high cost.
|
||||
// As such we delay the retrieval of the entry to the first call to entry().
|
||||
}
|
||||
|
||||
/// Copy assignment operator.
|
||||
///
|
||||
/// Differs from the default copy assignment
|
||||
/// operator in that it does not copy the entry.
|
||||
///
|
||||
/// \param other The base iterator to copy.
|
||||
/// \return The base iterator instance.
|
||||
BaseIterator& operator=(const BaseIterator& other) noexcept {
|
||||
if (this != &other) {
|
||||
_iterator = other._iterator;
|
||||
_cache = other._cache;
|
||||
_entry.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Move constructor.
|
||||
BaseIterator(BaseIterator&& other) noexcept = default;
|
||||
|
||||
/// Move assignment operator.
|
||||
BaseIterator& operator=(BaseIterator&& other) noexcept = default;
|
||||
|
||||
/// Generalized copy constructor.
|
||||
///
|
||||
/// Mainly necessary for non-const to const conversion.
|
||||
///
|
||||
/// \param other The base iterator to copy from.
|
||||
template <typename AnyIteratorTag,
|
||||
typename AnyKeyType,
|
||||
typename AnyValueType,
|
||||
typename AnyCacheType,
|
||||
typename AnyUnderlyingIteratorType>
|
||||
BaseIterator(const BaseIterator<AnyIteratorTag,
|
||||
AnyKeyType,
|
||||
AnyValueType,
|
||||
AnyCacheType,
|
||||
AnyUnderlyingIteratorType>& other)
|
||||
: _iterator(other._iterator), _entry(other._entry), _cache(other._cache) {
|
||||
}
|
||||
|
||||
/// Generalized move constructor.
|
||||
///
|
||||
/// Mainly necessary for non-const to const conversion.
|
||||
///
|
||||
/// \param other The base iterator to move into this one.
|
||||
template <typename AnyIteratorTag,
|
||||
typename AnyKeyType,
|
||||
typename AnyValueType,
|
||||
typename AnyCacheType,
|
||||
typename AnyUnderlyingIteratorType>
|
||||
BaseIterator(BaseIterator<AnyIteratorTag,
|
||||
AnyKeyType,
|
||||
AnyValueType,
|
||||
AnyCacheType,
|
||||
AnyUnderlyingIteratorType>&& other) noexcept
|
||||
: _iterator(std::move(other._iterator))
|
||||
, _entry(std::move(other._entry))
|
||||
, _cache(std::move(other._cache)) {
|
||||
}
|
||||
|
||||
/// Destructor.
|
||||
virtual ~BaseIterator() = default;
|
||||
|
||||
/// Swaps this base iterator with another one.
|
||||
///
|
||||
/// \param other The other iterator to swap with.
|
||||
void swap(BaseIterator& other) noexcept {
|
||||
// Enable ADL
|
||||
using std::swap;
|
||||
|
||||
swap(_iterator, other._iterator);
|
||||
swap(_entry, other._entry);
|
||||
swap(_cache, other._cache);
|
||||
}
|
||||
|
||||
/// Swaps two base iterator.
|
||||
///
|
||||
/// \param first The first iterator to swap.
|
||||
/// \param second The second iterator to swap.
|
||||
friend void swap(BaseIterator& first, BaseIterator& second) noexcept {
|
||||
first.swap(second);
|
||||
}
|
||||
|
||||
/// \returns A reference to the current entry pointed to by the iterator.
|
||||
virtual Entry& operator*() noexcept = 0;
|
||||
|
||||
/// \returns A pointer to the current entry pointed to by the iterator.
|
||||
Entry* operator->() noexcept {
|
||||
return &(**this);
|
||||
}
|
||||
|
||||
/// \copydoc operator*()
|
||||
virtual Entry& entry() = 0;
|
||||
|
||||
/// \returns A reference to the value of the entry currently pointed to by the
|
||||
/// iterator.
|
||||
virtual ValueType& value() = 0;
|
||||
|
||||
/// \returns A reference to the key of the entry currently pointed to by the
|
||||
/// iterator.
|
||||
virtual const Key& key() = 0;
|
||||
|
||||
protected:
|
||||
template <typename, typename, typename, typename, typename>
|
||||
friend class BaseIterator;
|
||||
|
||||
/// The underlying iterator this iterator class adapts.
|
||||
UnderlyingIterator _iterator;
|
||||
|
||||
/// The entry optionally being stored.
|
||||
Optional<Entry> _entry;
|
||||
|
||||
/// A pointer to the cache this iterator points into.
|
||||
/// Pointer and not reference because it's cheap to copy.
|
||||
/// Pointer and not `std::reference_wrapper` because the class needs to be
|
||||
/// default-constructible.
|
||||
Cache* _cache;
|
||||
};
|
||||
} // namespace Internal
|
||||
} // namespace LRU
|
||||
|
||||
#endif // LRU_INTERNAL_BASE_ITERATOR_HPP
|
||||
338
src/3rdParty/lru-cache/include/lru/internal/base-ordered-iterator.hpp
vendored
Normal file
338
src/3rdParty/lru-cache/include/lru/internal/base-ordered-iterator.hpp
vendored
Normal file
@@ -0,0 +1,338 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef BASE_ORDERED_ITERATOR_HPP
|
||||
#define BASE_ORDERED_ITERATOR_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
#include <lru/entry.hpp>
|
||||
#include <lru/error.hpp>
|
||||
#include <lru/internal/base-iterator.hpp>
|
||||
#include <lru/internal/base-unordered-iterator.hpp>
|
||||
#include <lru/internal/definitions.hpp>
|
||||
#include <lru/internal/optional.hpp>
|
||||
#include <lru/iterator-tags.hpp>
|
||||
|
||||
namespace LRU {
|
||||
namespace Internal {
|
||||
|
||||
template <typename Key, typename Value, typename Cache>
|
||||
using BaseForBaseOrderedIterator =
|
||||
BaseIterator<std::bidirectional_iterator_tag,
|
||||
Key,
|
||||
Value,
|
||||
Cache,
|
||||
typename Queue<Key>::const_iterator>;
|
||||
|
||||
/// The base class for all const and non-const ordered iterators.
|
||||
///
|
||||
/// Ordered iterators are bidirectional iterators that iterate over the keys of
|
||||
/// a cache in the order in which they were inserted into the cache. As they
|
||||
/// only iterate over the keys, they must perform hash lookups to retrieve the
|
||||
/// value the first time they are dereferenced. This makes them slightly less
|
||||
/// efficient than unordered iterators. However, they also have the additional
|
||||
/// property that they may be constructed from unordered iterators, and that
|
||||
/// they can be decremented.
|
||||
///
|
||||
/// \tparam Key The key type over which instances of the iterator iterate.
|
||||
/// \tparam Value The value type over which instances of the iterator iterate.
|
||||
/// \tparam Cache The type of the cache instances of the iterator point into.
|
||||
template <typename Key, typename Value, typename Cache>
|
||||
class BaseOrderedIterator
|
||||
: public BaseForBaseOrderedIterator<Key, Value, Cache> {
|
||||
protected:
|
||||
using super = BaseForBaseOrderedIterator<Key, Value, Cache>;
|
||||
using PRIVATE_BASE_ITERATOR_MEMBERS;
|
||||
using UnderlyingIterator = typename Queue<Key>::const_iterator;
|
||||
|
||||
public:
|
||||
using Tag = LRU::Tag::OrderedIterator;
|
||||
using PUBLIC_BASE_ITERATOR_MEMBERS;
|
||||
|
||||
/// Constructor.
|
||||
BaseOrderedIterator() noexcept = default;
|
||||
|
||||
/// \copydoc BaseIterator::BaseIterator(Cache,UnderlyingIterator)
|
||||
BaseOrderedIterator(Cache& cache, UnderlyingIterator iterator)
|
||||
: super(cache, iterator) {
|
||||
}
|
||||
|
||||
/// Generalized copy constructor.
|
||||
///
|
||||
/// \param other The ordered iterator to contruct from.
|
||||
template <typename AnyKey, typename AnyValue, typename AnyCache>
|
||||
BaseOrderedIterator(
|
||||
const BaseOrderedIterator<AnyKey, AnyValue, AnyCache>& other)
|
||||
: super(other) {
|
||||
}
|
||||
|
||||
/// Generalized move constructor.
|
||||
///
|
||||
/// \param other The ordered iterator to move into this one.
|
||||
template <typename AnyKey, typename AnyValue, typename AnyCache>
|
||||
BaseOrderedIterator(BaseOrderedIterator<AnyKey, AnyValue, AnyCache>&& other)
|
||||
: super(std::move(other)) {
|
||||
}
|
||||
|
||||
/// Generalized conversion copy constructor.
|
||||
///
|
||||
/// \param unordered_iterator The unordered iterator to construct from.
|
||||
template <
|
||||
typename AnyCache,
|
||||
typename UnderlyingIterator,
|
||||
typename = std::enable_if_t<
|
||||
std::is_same<std::decay_t<AnyCache>, std::decay_t<Cache>>::value>>
|
||||
BaseOrderedIterator(const BaseUnorderedIterator<AnyCache, UnderlyingIterator>&
|
||||
unordered_iterator) {
|
||||
// Atomicity
|
||||
_throw_if_at_invalid(unordered_iterator);
|
||||
_cache = unordered_iterator._cache;
|
||||
_iterator = unordered_iterator._iterator->second.order;
|
||||
}
|
||||
|
||||
/// Generalized conversion move constructor.
|
||||
///
|
||||
/// \param unordered_iterator The unordered iterator to move-construct from.
|
||||
template <
|
||||
typename AnyCache,
|
||||
typename UnderlyingIterator,
|
||||
typename = std::enable_if_t<
|
||||
std::is_same<std::decay_t<AnyCache>, std::decay_t<Cache>>::value>>
|
||||
BaseOrderedIterator(BaseUnorderedIterator<AnyCache, UnderlyingIterator>&&
|
||||
unordered_iterator) {
|
||||
// Atomicity
|
||||
_throw_if_at_invalid(unordered_iterator);
|
||||
_cache = std::move(unordered_iterator._cache);
|
||||
_entry = std::move(unordered_iterator._entry);
|
||||
_iterator = std::move(unordered_iterator._iterator->second.order);
|
||||
}
|
||||
|
||||
/// Copy constructor.
|
||||
BaseOrderedIterator(const BaseOrderedIterator& other) = default;
|
||||
|
||||
/// Move constructor.
|
||||
BaseOrderedIterator(BaseOrderedIterator&& other) = default;
|
||||
|
||||
/// Copy assignment operator.
|
||||
BaseOrderedIterator& operator=(const BaseOrderedIterator& other) = default;
|
||||
|
||||
/// Move assignment operator.
|
||||
BaseOrderedIterator& operator=(BaseOrderedIterator&& other) = default;
|
||||
|
||||
/// Destructor.
|
||||
virtual ~BaseOrderedIterator() = default;
|
||||
|
||||
/// Checks for equality between this iterator and another ordered iterator.
|
||||
///
|
||||
/// \param other The other ordered iterator.
|
||||
/// \returns True if both iterators point to the same entry, else false.
|
||||
bool operator==(const BaseOrderedIterator& other) const noexcept {
|
||||
return this->_iterator == other._iterator;
|
||||
}
|
||||
|
||||
/// Checks for inequality between this iterator another ordered iterator.
|
||||
///
|
||||
/// \param other The other ordered iterator.
|
||||
/// \returns True if the iterators point to different entries, else false.
|
||||
bool operator!=(const BaseOrderedIterator& other) const noexcept {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
/// Checks for inequality between this iterator and another unordered
|
||||
/// iterator.
|
||||
///
|
||||
/// \param other The other unordered iterator.
|
||||
/// \returns True if both iterators point to the end of the same cache, else
|
||||
/// the result of comparing with the unordered iterator, converted to an
|
||||
/// ordered iterator.
|
||||
template <typename AnyCache, typename AnyUnderlyingIterator>
|
||||
bool operator==(
|
||||
const BaseUnorderedIterator<AnyCache, AnyUnderlyingIterator>& other) const
|
||||
noexcept {
|
||||
if (this->_cache != other._cache) return false;
|
||||
|
||||
// The past-the-end iterators of the same cache should compare equal.
|
||||
// This is an exceptional guarantee we make. This is also the reason
|
||||
// why we can't rely on the conversion from unordered to ordered iterators
|
||||
// because construction of an ordered iterator from the past-the-end
|
||||
// unordered iterator will fail (with an InvalidIteratorConversion error)
|
||||
if (other == other._cache->unordered_end()) {
|
||||
return *this == this->_cache->ordered_end();
|
||||
}
|
||||
|
||||
// Will call the other overload
|
||||
return *this == static_cast<BaseOrderedIterator>(other);
|
||||
}
|
||||
|
||||
/// Checks for equality between an unordered iterator and an ordered iterator.
|
||||
///
|
||||
/// \param first The unordered iterator.
|
||||
/// \param second The ordered iterator.
|
||||
/// \returns True if both iterators point to the end of the same cache, else
|
||||
/// the result of comparing with the unordered iterator, converted to an
|
||||
/// ordered iterator.
|
||||
template <typename AnyCache, typename AnyUnderlyingIterator>
|
||||
friend bool operator==(
|
||||
const BaseUnorderedIterator<AnyCache, AnyUnderlyingIterator>& first,
|
||||
const BaseOrderedIterator& second) noexcept {
|
||||
return second == first;
|
||||
}
|
||||
|
||||
/// Checks for inequality between an unordered
|
||||
/// iterator and an ordered iterator.
|
||||
///
|
||||
/// \param first The ordered iterator.
|
||||
/// \param second The unordered iterator.
|
||||
/// \returns True if the iterators point to different entries, else false.
|
||||
template <typename AnyCache, typename AnyUnderlyingIterator>
|
||||
friend bool
|
||||
operator!=(const BaseOrderedIterator& first,
|
||||
const BaseUnorderedIterator<AnyCache, AnyUnderlyingIterator>&
|
||||
second) noexcept {
|
||||
return !(first == second);
|
||||
}
|
||||
|
||||
/// Checks for inequality between an unordered
|
||||
/// iterator and an ordered iterator.
|
||||
///
|
||||
/// \param first The unordered iterator.
|
||||
/// \param second The ordered iterator.
|
||||
/// \returns True if the iterators point to different entries, else false.
|
||||
template <typename AnyCache, typename AnyUnderlyingIterator>
|
||||
friend bool operator!=(
|
||||
const BaseUnorderedIterator<AnyCache, AnyUnderlyingIterator>& first,
|
||||
const BaseOrderedIterator& second) noexcept {
|
||||
return second != first;
|
||||
}
|
||||
|
||||
/// Increments the iterator to the next entry.
|
||||
///
|
||||
/// If the iterator already pointed to the end any number of increments
|
||||
/// before, behavior is undefined.
|
||||
///
|
||||
/// \returns The resulting iterator.
|
||||
BaseOrderedIterator& operator++() {
|
||||
++_iterator;
|
||||
_entry.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Increments the iterator and returns a copy of the previous one.
|
||||
///
|
||||
/// If the iterator already pointed to the end any number of increments
|
||||
/// before, behavior is undefined.
|
||||
///
|
||||
/// \returns A copy of the previous iterator.
|
||||
BaseOrderedIterator operator++(int) {
|
||||
auto previous = *this;
|
||||
++*this;
|
||||
return previous;
|
||||
}
|
||||
|
||||
/// Decrements the iterator to the previous entry.
|
||||
///
|
||||
/// \returns The resulting iterator.
|
||||
BaseOrderedIterator& operator--() {
|
||||
--_iterator;
|
||||
_entry.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Decrements the iterator and returns a copy of the previous entry.
|
||||
///
|
||||
/// \returns The previous iterator.
|
||||
BaseOrderedIterator operator--(int) {
|
||||
auto previous = *this;
|
||||
--*this;
|
||||
return previous;
|
||||
}
|
||||
|
||||
Entry& operator*() noexcept override {
|
||||
return _maybe_lookup();
|
||||
}
|
||||
|
||||
/// \returns A reference to the entry the iterator points to.
|
||||
/// \details If the iterator is invalid, behavior is undefined.
|
||||
Entry& entry() override {
|
||||
_cache->throw_if_invalid(*this);
|
||||
return _maybe_lookup();
|
||||
}
|
||||
|
||||
/// \returns A reference to the value the iterator points to.
|
||||
/// \details If the iterator is invalid, behavior is undefined.
|
||||
Value& value() override {
|
||||
return entry().value();
|
||||
}
|
||||
|
||||
/// \returns A reference to the key the iterator points to.
|
||||
/// \details If the iterator is invalid, behavior is undefined.
|
||||
const Key& key() override {
|
||||
// No lookup required
|
||||
_cache->throw_if_invalid(*this);
|
||||
return *_iterator;
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename, typename, typename>
|
||||
friend class BaseOrderedIterator;
|
||||
|
||||
/// Looks up the entry for a key if this was not done already.
|
||||
///
|
||||
/// \returns The entry, which was possibly newly looked up.
|
||||
Entry& _maybe_lookup() {
|
||||
if (!_entry.has_value()) {
|
||||
_lookup();
|
||||
}
|
||||
|
||||
return *_entry;
|
||||
}
|
||||
|
||||
/// Looks up the entry for a key and sets the internal entry member.
|
||||
void _lookup() {
|
||||
auto iterator = _cache->_map.find(*_iterator);
|
||||
_entry.emplace(iterator->first, iterator->second.value);
|
||||
}
|
||||
|
||||
private:
|
||||
/// Throws an exception if the given unordered iterator is invalid.
|
||||
///
|
||||
/// \param unordered_iterator The iterator to check.
|
||||
/// \throws LRU::Error::InvalidIteratorConversion if the iterator is invalid.
|
||||
template <typename UnorderedIterator>
|
||||
void _throw_if_at_invalid(const UnorderedIterator& unordered_iterator) {
|
||||
// For atomicity of the copy assignment, we assign the cache pointer only
|
||||
// after this check in the copy/move constructor and use the iterator's
|
||||
// cache. If an exception is thrown, the state of the ordered iterator is
|
||||
// unchanged compared to before the assignment.
|
||||
if (unordered_iterator == unordered_iterator._cache->unordered_end()) {
|
||||
throw LRU::Error::InvalidIteratorConversion();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace LRU
|
||||
|
||||
#endif // BASE_ORDERED_ITERATOR_HPP
|
||||
216
src/3rdParty/lru-cache/include/lru/internal/base-unordered-iterator.hpp
vendored
Normal file
216
src/3rdParty/lru-cache/include/lru/internal/base-unordered-iterator.hpp
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef BASE_UNORDERED_ITERATOR_HPP
|
||||
#define BASE_UNORDERED_ITERATOR_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
#include <lru/entry.hpp>
|
||||
#include <lru/internal/base-iterator.hpp>
|
||||
#include <lru/internal/definitions.hpp>
|
||||
#include <lru/internal/optional.hpp>
|
||||
#include <lru/iterator-tags.hpp>
|
||||
|
||||
|
||||
namespace LRU {
|
||||
|
||||
// Forward declaration.
|
||||
template <typename, typename, typename, typename, typename>
|
||||
class TimedCache;
|
||||
|
||||
namespace Internal {
|
||||
template <typename Cache, typename UnderlyingIterator>
|
||||
using BaseForBaseUnorderedIterator =
|
||||
BaseIterator<std::forward_iterator_tag,
|
||||
decltype(UnderlyingIterator()->first),
|
||||
decltype(UnderlyingIterator()->second.value),
|
||||
Cache,
|
||||
UnderlyingIterator>;
|
||||
|
||||
/// The base class for all const and non-const unordered iterators.
|
||||
///
|
||||
/// An unordered iterator is a wrapper around an `unordered_map` iterator with
|
||||
/// ForwardIterator category. As such, it is (nearly) as fast to access the pair
|
||||
/// as through the unordered iterator as through the map iterator directly.
|
||||
/// However, the order of keys is unspecified. For this reason, unordered
|
||||
/// iterators have the special property that they may be used to construct
|
||||
/// ordered iterators, after which the order of insertion is respected.
|
||||
///
|
||||
/// \tparam Cache The type of the cache instances of the iterator point into.
|
||||
/// \tparam UnderlyingIterator The underlying iterator class used to implement
|
||||
/// the iterator.
|
||||
template <typename Cache, typename UnderlyingIterator>
|
||||
class BaseUnorderedIterator
|
||||
: public BaseForBaseUnorderedIterator<Cache, UnderlyingIterator> {
|
||||
protected:
|
||||
using super = BaseForBaseUnorderedIterator<Cache, UnderlyingIterator>;
|
||||
using PRIVATE_BASE_ITERATOR_MEMBERS;
|
||||
// These are the key and value types the BaseIterator extracts
|
||||
using Key = typename super::KeyType;
|
||||
using Value = typename super::ValueType;
|
||||
|
||||
public:
|
||||
using Tag = LRU::Tag::UnorderedIterator;
|
||||
using PUBLIC_BASE_ITERATOR_MEMBERS;
|
||||
|
||||
/// Constructor.
|
||||
BaseUnorderedIterator() noexcept = default;
|
||||
|
||||
/// \copydoc BaseIterator::BaseIterator(Cache,UnderlyingIterator)
|
||||
explicit BaseUnorderedIterator(Cache& cache,
|
||||
const UnderlyingIterator& iterator) noexcept
|
||||
: super(cache, iterator) {
|
||||
}
|
||||
|
||||
/// Generalized copy constructor.
|
||||
///
|
||||
/// Useful mainly for non-const to const conversion.
|
||||
///
|
||||
/// \param other The iterator to copy from.
|
||||
template <typename AnyCache, typename AnyUnderlyingIterator>
|
||||
BaseUnorderedIterator(
|
||||
const BaseUnorderedIterator<AnyCache, AnyUnderlyingIterator>&
|
||||
other) noexcept
|
||||
: super(other) {
|
||||
}
|
||||
|
||||
/// Copy constructor.
|
||||
BaseUnorderedIterator(const BaseUnorderedIterator& other) noexcept = default;
|
||||
|
||||
/// Move constructor.
|
||||
BaseUnorderedIterator(BaseUnorderedIterator&& other) noexcept = default;
|
||||
|
||||
/// Copy assignment operator.
|
||||
BaseUnorderedIterator&
|
||||
operator=(const BaseUnorderedIterator& other) noexcept = default;
|
||||
|
||||
/// Move assignment operator.
|
||||
template <typename AnyCache, typename AnyUnderlyingIterator>
|
||||
BaseUnorderedIterator&
|
||||
operator=(BaseUnorderedIterator<AnyCache, AnyUnderlyingIterator>
|
||||
unordered_iterator) noexcept {
|
||||
swap(unordered_iterator);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Destructor.
|
||||
virtual ~BaseUnorderedIterator() = default;
|
||||
|
||||
/// Compares this iterator for equality with another unordered iterator.
|
||||
///
|
||||
/// \param other Another unordered iterator.
|
||||
/// \returns True if both iterators point to the same entry, else false.
|
||||
template <typename AnyCache, typename AnyIterator>
|
||||
bool
|
||||
operator==(const BaseUnorderedIterator<AnyCache, AnyIterator>& other) const
|
||||
noexcept {
|
||||
return this->_iterator == other._iterator;
|
||||
}
|
||||
|
||||
/// Compares this iterator for inequality with another unordered iterator.
|
||||
///
|
||||
/// \param other Another unordered iterator.
|
||||
/// \returns True if the iterators point to different entries, else false.
|
||||
template <typename AnyCache, typename AnyIterator>
|
||||
bool
|
||||
operator!=(const BaseUnorderedIterator<AnyCache, AnyIterator>& other) const
|
||||
noexcept {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
/// Increments the iterator to the next entry.
|
||||
///
|
||||
/// If the iterator already pointed to the end any number of increments
|
||||
/// before, behavior is undefined.
|
||||
///
|
||||
/// \returns The resulting iterator.
|
||||
BaseUnorderedIterator& operator++() {
|
||||
++_iterator;
|
||||
_entry.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Increments the iterator and returns a copy of the previous one.
|
||||
///
|
||||
/// If the iterator already pointed to the end any number of increments
|
||||
/// before, behavior is undefined.
|
||||
///
|
||||
/// \returns A copy of the previous iterator.
|
||||
BaseUnorderedIterator operator++(int) {
|
||||
auto previous = *this;
|
||||
++*this;
|
||||
return previous;
|
||||
}
|
||||
|
||||
/// \copydoc BaseIterator::operator*
|
||||
/// \details If the iterator is invalid, behavior is undefined. No exception
|
||||
/// handling is performed.
|
||||
Entry& operator*() noexcept override {
|
||||
if (!_entry.has_value()) {
|
||||
_entry.emplace(_iterator->first, _iterator->second.value);
|
||||
}
|
||||
|
||||
return *_entry;
|
||||
}
|
||||
|
||||
/// \returns A reference to the entry the iterator points to.
|
||||
/// \throws LRU::Error::InvalidIterator if the iterator is the end iterator.
|
||||
/// \throws LRU::Error::KeyExpired if the key pointed to by the iterator has
|
||||
/// expired.
|
||||
Entry& entry() override {
|
||||
if (!_entry.has_value()) {
|
||||
_entry.emplace(_iterator->first, _iterator->second.value);
|
||||
}
|
||||
|
||||
_cache->throw_if_invalid(*this);
|
||||
return *_entry;
|
||||
}
|
||||
|
||||
/// \returns A reference to the key the iterator points to.
|
||||
/// \throws LRU::Error::InvalidIterator if the iterator is the end iterator.
|
||||
/// \throws LRU::Error::KeyExpired if the key pointed to by the iterator has
|
||||
/// expired.
|
||||
const Key& key() override {
|
||||
return entry().key();
|
||||
}
|
||||
|
||||
/// \returns A reference to the value the iterator points to.
|
||||
/// \throws LRU::Error::InvalidIterator if the iterator is the end iterator.
|
||||
/// \throws LRU::Error::KeyExpired if the key pointed to by the iterator has
|
||||
/// expired.
|
||||
Value& value() override {
|
||||
return entry().value();
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename, typename, typename>
|
||||
friend class BaseOrderedIterator;
|
||||
|
||||
template <typename, typename, typename, typename, typename>
|
||||
friend class LRU::TimedCache;
|
||||
};
|
||||
} // namespace Internal
|
||||
} // namespace LRU
|
||||
|
||||
#endif // BASE_UNORDERED_ITERATOR_HPP
|
||||
159
src/3rdParty/lru-cache/include/lru/internal/callback-manager.hpp
vendored
Normal file
159
src/3rdParty/lru-cache/include/lru/internal/callback-manager.hpp
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef LRU_INTERNAL_CALLBACK_MANAGER_HPP
|
||||
#define LRU_INTERNAL_CALLBACK_MANAGER_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#include <lru/entry.hpp>
|
||||
#include <lru/internal/optional.hpp>
|
||||
|
||||
namespace LRU {
|
||||
namespace Internal {
|
||||
|
||||
/// Manages hit, miss and access callbacks for a cache.
|
||||
///
|
||||
/// The callback manager implements the "publisher" of the observer pattern we
|
||||
/// implement. It stores and calls three kinds of callbacks:
|
||||
/// 1. Hit callbacks, taking a key and value after a cache hit.
|
||||
/// 2. Miss callbacks, taking only a key, that was not found in a cache.
|
||||
/// 3. Access callbacks, taking a key and a boolean indicating a hit or a miss.
|
||||
///
|
||||
/// Callbacks can be added, accessed and cleared.
|
||||
template <typename Key, typename Value>
|
||||
class CallbackManager {
|
||||
public:
|
||||
using HitCallback = std::function<void(const Key&, const Value&)>;
|
||||
using MissCallback = std::function<void(const Key&)>;
|
||||
using AccessCallback = std::function<void(const Key&, bool)>;
|
||||
|
||||
using HitCallbackContainer = std::vector<HitCallback>;
|
||||
using MissCallbackContainer = std::vector<MissCallback>;
|
||||
using AccessCallbackContainer = std::vector<AccessCallback>;
|
||||
|
||||
/// Calls all callbacks registered for a hit, with the given key and value.
|
||||
///
|
||||
/// \param key The key for which a cache hit ocurred.
|
||||
/// \param value The value that was found for the key.
|
||||
void hit(const Key& key, const Value& value) {
|
||||
_call_each(_hit_callbacks, key, value);
|
||||
_call_each(_access_callbacks, key, true);
|
||||
}
|
||||
|
||||
/// Calls all callbacks registered for a miss, with the given key.
|
||||
///
|
||||
/// \param key The key for which a cache miss ocurred.
|
||||
void miss(const Key& key) {
|
||||
_call_each(_miss_callbacks, key);
|
||||
_call_each(_access_callbacks, key, false);
|
||||
}
|
||||
|
||||
/// Registers a new hit callback.
|
||||
///
|
||||
/// \param hit_callback The hit callback function to register with the
|
||||
/// manager.
|
||||
template <typename Callback>
|
||||
void hit_callback(Callback&& hit_callback) {
|
||||
_hit_callbacks.emplace_back(std::forward<Callback>(hit_callback));
|
||||
}
|
||||
|
||||
/// Registers a new miss callback.
|
||||
///
|
||||
/// \param miss_callback The miss callback function to register with the
|
||||
/// manager.
|
||||
template <typename Callback>
|
||||
void miss_callback(Callback&& miss_callback) {
|
||||
_miss_callbacks.emplace_back(std::forward<Callback>(miss_callback));
|
||||
}
|
||||
|
||||
/// Registers a new access callback.
|
||||
///
|
||||
/// \param access_callback The access callback function to register with the
|
||||
/// manager.
|
||||
template <typename Callback>
|
||||
void access_callback(Callback&& access_callback) {
|
||||
_access_callbacks.emplace_back(std::forward<Callback>(access_callback));
|
||||
}
|
||||
|
||||
/// Clears all hit callbacks.
|
||||
void clear_hit_callbacks() {
|
||||
_hit_callbacks.clear();
|
||||
}
|
||||
|
||||
/// Clears all miss callbacks.
|
||||
void clear_miss_callbacks() {
|
||||
_miss_callbacks.clear();
|
||||
}
|
||||
|
||||
/// Clears all access callbacks.
|
||||
void clear_access_callbacks() {
|
||||
_access_callbacks.clear();
|
||||
}
|
||||
|
||||
/// Clears all callbacks.
|
||||
void clear() {
|
||||
clear_hit_callbacks();
|
||||
clear_miss_callbacks();
|
||||
clear_access_callbacks();
|
||||
}
|
||||
|
||||
/// \returns All hit callbacks.
|
||||
const HitCallbackContainer& hit_callbacks() const noexcept {
|
||||
return _hit_callbacks;
|
||||
}
|
||||
|
||||
/// \returns All miss callbacks.
|
||||
const MissCallbackContainer& miss_callbacks() const noexcept {
|
||||
return _miss_callbacks;
|
||||
}
|
||||
|
||||
/// \returns All access callbacks.
|
||||
const AccessCallbackContainer& access_callbacks() const noexcept {
|
||||
return _access_callbacks;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Calls each function in the given container with the given arguments.
|
||||
///
|
||||
/// \param callbacks The container of callbacks to call.
|
||||
/// \param args The arguments to call the callbacks with.
|
||||
template <typename CallbackContainer, typename... Args>
|
||||
void _call_each(const CallbackContainer& callbacks, Args&&... args) {
|
||||
for (const auto& callback : callbacks) {
|
||||
callback(std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
/// The container of hit callbacks registered.
|
||||
HitCallbackContainer _hit_callbacks;
|
||||
|
||||
/// The container of miss callbacks registered.
|
||||
MissCallbackContainer _miss_callbacks;
|
||||
|
||||
/// The container of access callbacks registered.
|
||||
AccessCallbackContainer _access_callbacks;
|
||||
};
|
||||
} // namespace Internal
|
||||
} // namespace LRU
|
||||
|
||||
#endif // LRU_INTERNAL_CALLBACK_MANAGER_HPP
|
||||
88
src/3rdParty/lru-cache/include/lru/internal/definitions.hpp
vendored
Normal file
88
src/3rdParty/lru-cache/include/lru/internal/definitions.hpp
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef LRU_INTERNAL_DEFINITIONS_HPP
|
||||
#define LRU_INTERNAL_DEFINITIONS_HPP
|
||||
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace LRU {
|
||||
namespace Internal {
|
||||
|
||||
/// The default capacity for all caches.
|
||||
const std::size_t DEFAULT_CAPACITY = 128;
|
||||
|
||||
/// The reference type use to store keys in the order queue.
|
||||
template <typename T>
|
||||
using Reference = std::reference_wrapper<T>;
|
||||
|
||||
/// Compares two References for equality.
|
||||
///
|
||||
/// This is necessary because `std::reference_wrapper` does not define any
|
||||
/// operator overloads. We do need them, however (e.g. for container
|
||||
/// comparison).
|
||||
///
|
||||
/// \param first The first reference to compare.
|
||||
/// \param second The second reference to compare.
|
||||
template <typename T, typename U>
|
||||
bool operator==(const Reference<T>& first, const Reference<U>& second) {
|
||||
return first.get() == second.get();
|
||||
}
|
||||
|
||||
/// Compares two References for inequality.
|
||||
///
|
||||
/// This is necessary because `std::reference_wrapper` does not define any
|
||||
/// operator overloads. We do need them, however (e.g. for container
|
||||
/// comparison).
|
||||
///
|
||||
/// \param first The first reference to compare.
|
||||
/// \param second The second reference to compare.
|
||||
template <typename T, typename U>
|
||||
bool operator!=(const Reference<T>& first, const Reference<U>& second) {
|
||||
return !(first == second);
|
||||
}
|
||||
|
||||
/// The default queue type used internally.
|
||||
template <typename T>
|
||||
using Queue = std::list<Reference<T>>;
|
||||
|
||||
/// The default map type used internally.
|
||||
template <typename Key,
|
||||
typename Information,
|
||||
typename HashFunction,
|
||||
typename KeyEqual>
|
||||
using Map = std::unordered_map<Key, Information, HashFunction, KeyEqual>;
|
||||
|
||||
/// The default clock used internally.
|
||||
using Clock = std::chrono::steady_clock;
|
||||
|
||||
/// The default timestamp (time point) used internally.
|
||||
using Timestamp = Clock::time_point;
|
||||
} // namespace Internal
|
||||
} // namespace LRU
|
||||
|
||||
|
||||
#endif // LRU_INTERNAL_DEFINITIONS_HPP
|
||||
62
src/3rdParty/lru-cache/include/lru/internal/hash.hpp
vendored
Normal file
62
src/3rdParty/lru-cache/include/lru/internal/hash.hpp
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef LRU_INTERNAL_HASH_HPP
|
||||
#define LRU_INTERNAL_HASH_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
|
||||
/// `std::hash` specialization to allow storing tuples as keys
|
||||
/// in `std::unordered_map`.
|
||||
///
|
||||
/// Essentially hashes all tuple elements and jumbles the
|
||||
/// individual hashes together.
|
||||
namespace std {
|
||||
template <typename... Ts>
|
||||
struct hash<std::tuple<Ts...>> {
|
||||
using argument_type = std::tuple<Ts...>;
|
||||
using result_type = std::size_t;
|
||||
|
||||
result_type operator()(const argument_type& argument) const {
|
||||
return hash_tuple(argument, std::make_index_sequence<sizeof...(Ts)>());
|
||||
}
|
||||
|
||||
private:
|
||||
template <std::size_t I, std::size_t... Is>
|
||||
result_type
|
||||
hash_tuple(const argument_type& tuple, std::index_sequence<I, Is...>) const {
|
||||
auto value = std::get<I>(tuple);
|
||||
auto current = std::hash<decltype(value)>{}(value);
|
||||
auto seed = hash_tuple(tuple, std::index_sequence<Is...>());
|
||||
|
||||
// http://www.boost.org/doc/libs/1_35_0/doc/html/boost/hash_combine_id241013.html
|
||||
return current + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
}
|
||||
|
||||
result_type hash_tuple(const argument_type&, std::index_sequence<>) const {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#endif // LRU_INTERNAL_HASH_HPP
|
||||
145
src/3rdParty/lru-cache/include/lru/internal/information.hpp
vendored
Normal file
145
src/3rdParty/lru-cache/include/lru/internal/information.hpp
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef LRU_INTERNAL_INFORMATION_HPP
|
||||
#define LRU_INTERNAL_INFORMATION_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include <lru/internal/definitions.hpp>
|
||||
#include <lru/internal/utility.hpp>
|
||||
|
||||
namespace LRU {
|
||||
namespace Internal {
|
||||
|
||||
/// The value type of internal maps, used to store a value and iterator.
|
||||
///
|
||||
/// This information object is the basis of an LRU cache, which must associated
|
||||
/// a value and such an order iterator with a key, such that the iterator may be
|
||||
/// moved to the front of the order when the key is updated with a new value.
|
||||
///
|
||||
/// \tparam Key The key type of the information.
|
||||
/// \tparam Value The value type of the information.
|
||||
template <typename Key, typename Value>
|
||||
struct Information {
|
||||
using KeyType = Key;
|
||||
using ValueType = Value;
|
||||
using QueueIterator = typename Internal::Queue<const Key>::const_iterator;
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param value_ The value for the information.
|
||||
/// \param order_ The order iterator for the information.
|
||||
explicit Information(const Value& value_,
|
||||
QueueIterator order_ = QueueIterator())
|
||||
: value(value_), order(order_) {
|
||||
}
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param order_ The order iterator for the information.
|
||||
/// \param value_arguments Any number of arguments to perfectly forward to the
|
||||
/// value type's constructor.
|
||||
// template <typename... ValueArguments>
|
||||
// Information(QueueIterator order_, ValueArguments&&... value_arguments)
|
||||
// : value(std::forward<ValueArguments>(value_arguments)...), order(order_) {
|
||||
// }
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param order_ The order iterator for the information.
|
||||
/// \param value_arguments A tuple of arguments to perfectly forward to the
|
||||
/// value type's constructor.
|
||||
///
|
||||
template <typename... ValueArguments>
|
||||
explicit Information(const std::tuple<ValueArguments...>& value_arguments,
|
||||
QueueIterator order_ = QueueIterator())
|
||||
: Information(
|
||||
order_, value_arguments, Internal::tuple_indices(value_arguments)) {
|
||||
}
|
||||
|
||||
/// Copy constructor.
|
||||
Information(const Information& other) = default;
|
||||
|
||||
/// Move constructor.
|
||||
Information(Information&& other) = default;
|
||||
|
||||
/// Copy assignment operator.
|
||||
Information& operator=(const Information& other) = default;
|
||||
|
||||
/// Move assignment operator.
|
||||
Information& operator=(Information&& other) = default;
|
||||
|
||||
/// Destructor.
|
||||
virtual ~Information() = default;
|
||||
|
||||
/// Compares the information for equality with another information object.
|
||||
///
|
||||
/// \param other The other information object to compare to.
|
||||
/// \returns True if key and value (not the iterator itself) of the two
|
||||
/// information objects are equal, else false.
|
||||
virtual bool operator==(const Information& other) const noexcept {
|
||||
if (this == &other) return true;
|
||||
if (this->value != other.value) return false;
|
||||
// We do not compare the iterator (because otherwise two containers
|
||||
// holding information would never be equal). We also do not compare
|
||||
// the key stored in the iterator, because keys will always have been
|
||||
// compared before this operator is called.
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Compares the information for inequality with another information object.
|
||||
///
|
||||
/// \param other The other information object to compare for.
|
||||
/// \returns True if key and value (not the iterator itself) of the two
|
||||
/// information objects are unequal, else false.
|
||||
virtual bool operator!=(const Information& other) const noexcept {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
/// The value of the information.
|
||||
Value value;
|
||||
|
||||
/// The order iterator of the information.
|
||||
QueueIterator order;
|
||||
|
||||
private:
|
||||
/// Implementation for the constructor taking a tuple of arguments for the
|
||||
/// value.
|
||||
///
|
||||
/// \param order_ The order iterator for the information.
|
||||
/// \param value_argument The tuple of arguments to perfectly forward to the
|
||||
/// value type's constructor.
|
||||
/// \param _ An index sequence to access the elements of the tuple
|
||||
template <typename... ValueArguments, std::size_t... Indices>
|
||||
Information(const QueueIterator& order_,
|
||||
const std::tuple<ValueArguments...>& value_argument,
|
||||
std::index_sequence<Indices...> _)
|
||||
: value(std::forward<ValueArguments>(std::get<Indices>(value_argument))...)
|
||||
, order(order_) {
|
||||
}
|
||||
};
|
||||
} // namespace Internal
|
||||
} // namespace LRU
|
||||
|
||||
#endif // LRU_INTERNAL_INFORMATION_HPP
|
||||
254
src/3rdParty/lru-cache/include/lru/internal/last-accessed.hpp
vendored
Normal file
254
src/3rdParty/lru-cache/include/lru/internal/last-accessed.hpp
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef LRU_INTERNAL_LAST_ACCESSED_HPP
|
||||
#define LRU_INTERNAL_LAST_ACCESSED_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
|
||||
#include <lru/internal/utility.hpp>
|
||||
|
||||
namespace LRU {
|
||||
namespace Internal {
|
||||
|
||||
/// Provides a simple iterator-compatible pointer object for a key and
|
||||
/// information.
|
||||
///
|
||||
/// The easisest idea for this class, theoretically, would be to just store an s
|
||||
/// iterator to the internal cache map (i.e. template the class on the iterator
|
||||
/// type). However, the major trouble with that approach is that this class
|
||||
/// should be 100% *mutable*, as in "always non-const", so that keys and
|
||||
/// informations
|
||||
/// we store for fast access can be (quickly) retrieved as either const or
|
||||
/// non-const (iterators for example). This is not possible, since the
|
||||
/// const-ness of `const_iterators` are not the usual idea of const in C++,
|
||||
/// meaning especially it cannot be cast away with a `const_cast` as is required
|
||||
/// for the mutability. As such, we *must* store the plain keys and
|
||||
/// informations.
|
||||
/// This, however, means that iterators cannot be stored efficiently, since a
|
||||
/// new hash table lookup would be required to go from a key to its iterator.
|
||||
/// However, since the main use case of this class is to avoid a second lookup
|
||||
/// in the usual `if (cache.contains(key)) return cache.lookup(key)`, which is
|
||||
/// not an issue for iterators since they can be compared to the `end` iterator
|
||||
/// in constant time (equivalent to the call to `contains()`).
|
||||
///
|
||||
/// WARNING: This class stores *pointers* to keys and informations. As such
|
||||
/// lifetime
|
||||
/// of the pointed-to objects must be cared for by the user of this class.
|
||||
///
|
||||
/// \tparam Key The type of key being accessed.
|
||||
/// \tparam InformationType The type of information being accessed.
|
||||
/// \tparam KeyEqual The type of the key comparison function.
|
||||
template <typename Key,
|
||||
typename InformationType,
|
||||
typename KeyEqual = std::equal_to<Key>>
|
||||
class LastAccessed {
|
||||
public:
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param key_equal The function to compare keys with.
|
||||
explicit LastAccessed(const KeyEqual& key_equal = KeyEqual())
|
||||
: _key(nullptr)
|
||||
, _information(nullptr)
|
||||
, _is_valid(false)
|
||||
, _key_equal(key_equal) {
|
||||
}
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param key The key to store a reference to.
|
||||
/// \param information The information to store a reference to.
|
||||
/// \param key_equal The function to compare keys with.
|
||||
LastAccessed(const Key& key,
|
||||
const InformationType& information,
|
||||
const KeyEqual& key_equal = KeyEqual())
|
||||
: _key(const_cast<Key*>(&key))
|
||||
, _information(const_cast<InformationType*>(&information))
|
||||
, _is_valid(true)
|
||||
, _key_equal(key_equal) {
|
||||
}
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param iterator An iterator pointing to a key and information to use for
|
||||
/// constructing the instance.
|
||||
/// \param key_equal The function to compare keys with.
|
||||
template <typename Iterator>
|
||||
explicit LastAccessed(Iterator iterator,
|
||||
const KeyEqual& key_equal = KeyEqual())
|
||||
: LastAccessed(iterator->first, iterator->second, key_equal) {
|
||||
}
|
||||
|
||||
/// Copy assignment operator for iterators.
|
||||
///
|
||||
/// \param iterator An iterator pointing to a key and value to use for the
|
||||
/// `LastAccessed` instance.
|
||||
/// \return The resulting `LastAccessed` instance.
|
||||
template <typename Iterator>
|
||||
LastAccessed& operator=(Iterator iterator) {
|
||||
_key = const_cast<Key*>(&(iterator->first));
|
||||
_information = const_cast<InformationType*>(&(iterator->second));
|
||||
_is_valid = true;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Compares a `LastAccessed` object for equality with a key.
|
||||
///
|
||||
/// \param last_accessed The `LastAccessed` instance to compare.
|
||||
/// \param key The key instance to compare.
|
||||
/// \returns True if the key of the `LastAccessed` object's key equals the
|
||||
/// given key, else false.
|
||||
friend bool
|
||||
operator==(const LastAccessed& last_accessed, const Key& key) noexcept {
|
||||
if (!last_accessed._is_valid) return false;
|
||||
return last_accessed._key_equal(key, last_accessed.key());
|
||||
}
|
||||
|
||||
/// \copydoc operator==(const LastAccessed&,const Key&)
|
||||
friend bool
|
||||
operator==(const Key& key, const LastAccessed& last_accessed) noexcept {
|
||||
return last_accessed == key;
|
||||
}
|
||||
|
||||
/// Compares a `LastAccessed` object for equality with an iterator.
|
||||
///
|
||||
/// \param last_accessed The `LastAccessed` instance to compare.
|
||||
/// \param iterator The iterator to compare with.
|
||||
/// \returns True if the `LastAccessed` object's key equals that of the
|
||||
/// iterator, else false.
|
||||
template <typename Iterator, typename = enable_if_iterator<Iterator>>
|
||||
friend bool
|
||||
operator==(const LastAccessed& last_accessed, Iterator iterator) noexcept {
|
||||
/// Fast comparisons to an iterator (not relying on implicit conversion)
|
||||
return last_accessed == iterator->first;
|
||||
}
|
||||
|
||||
/// \copydoc operator==(const LastAccessed&,Iterator)
|
||||
template <typename Iterator, typename = enable_if_iterator<Iterator>>
|
||||
friend bool
|
||||
operator==(Iterator iterator, const LastAccessed& last_accessed) noexcept {
|
||||
return last_accessed == iterator;
|
||||
}
|
||||
|
||||
/// Compares a `LastAccessed` object for inequality with something.
|
||||
///
|
||||
/// \param last_accessed The `LastAccessed` instance to compare.
|
||||
/// \param other Something else to compare to.
|
||||
/// \returns True if the key of the `LastAccessed` object's key does not equal
|
||||
/// the given other object's key, else false.
|
||||
template <typename T>
|
||||
friend bool
|
||||
operator!=(const LastAccessed& last_accessed, const T& other) noexcept {
|
||||
return !(last_accessed == other);
|
||||
}
|
||||
|
||||
/// \copydoc operator!=(const LastAccessed&,const T&)
|
||||
template <typename T>
|
||||
friend bool
|
||||
operator!=(const T& other, const LastAccessed& last_accessed) noexcept {
|
||||
return !(other == last_accessed);
|
||||
}
|
||||
|
||||
/// \returns The last accessed key.
|
||||
Key& key() noexcept {
|
||||
assert(is_valid());
|
||||
return *_key;
|
||||
}
|
||||
|
||||
/// \returns The last accessed key.
|
||||
const Key& key() const noexcept {
|
||||
assert(is_valid());
|
||||
return *_key;
|
||||
}
|
||||
|
||||
/// \returns The last accessed information.
|
||||
InformationType& information() noexcept {
|
||||
assert(is_valid());
|
||||
return *_information;
|
||||
}
|
||||
|
||||
/// \returns The last accessed information.
|
||||
const InformationType& information() const noexcept {
|
||||
assert(is_valid());
|
||||
return *_information;
|
||||
}
|
||||
|
||||
/// \returns The last accessed information.
|
||||
auto& iterator() noexcept {
|
||||
assert(is_valid());
|
||||
return _information->order;
|
||||
}
|
||||
|
||||
/// \returns The last accessed value.
|
||||
auto& value() noexcept {
|
||||
assert(is_valid());
|
||||
return _information->value;
|
||||
}
|
||||
|
||||
/// \returns The last accessed value.
|
||||
const auto& value() const noexcept {
|
||||
assert(is_valid());
|
||||
return _information->value;
|
||||
}
|
||||
|
||||
/// \returns True if the key and information of the instance may be accessed,
|
||||
/// else false.
|
||||
bool is_valid() const noexcept {
|
||||
return _is_valid;
|
||||
}
|
||||
|
||||
/// \copydoc is_valid()
|
||||
explicit operator bool() const noexcept {
|
||||
return is_valid();
|
||||
}
|
||||
|
||||
/// Invalidates the instance.
|
||||
void invalidate() noexcept {
|
||||
_is_valid = false;
|
||||
_key = nullptr;
|
||||
_information = nullptr;
|
||||
}
|
||||
|
||||
/// \returns The key comparison function used.
|
||||
const KeyEqual& key_equal() const noexcept {
|
||||
return _key_equal;
|
||||
}
|
||||
|
||||
private:
|
||||
/// A pointer to the key that was last accessed (if any).
|
||||
Key* _key;
|
||||
|
||||
/// A pointer to the information that was last accessed (if any).
|
||||
InformationType* _information;
|
||||
|
||||
/// True if the key and information pointers are valid, else false.
|
||||
bool _is_valid;
|
||||
|
||||
/// The function used to compare keys.
|
||||
KeyEqual _key_equal;
|
||||
};
|
||||
} // namespace Internal
|
||||
} // namespace LRU
|
||||
|
||||
#endif // LRU_INTERNAL_LAST_ACCESSED_HPP
|
||||
207
src/3rdParty/lru-cache/include/lru/internal/optional.hpp
vendored
Normal file
207
src/3rdParty/lru-cache/include/lru/internal/optional.hpp
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef LRU_INTERNAL_OPTIONAL_HPP
|
||||
#define LRU_INTERNAL_OPTIONAL_HPP
|
||||
|
||||
#ifndef __has_include
|
||||
#define USE_LRU_OPTIONAL
|
||||
#elif __has_include(<optional>)
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace LRU {
|
||||
namespace Internal {
|
||||
template <typename T>
|
||||
using Optional = std::optional<T>;
|
||||
} // namespace Internal
|
||||
} // namespace LRU
|
||||
|
||||
#else
|
||||
#define USE_LRU_OPTIONAL
|
||||
#endif
|
||||
|
||||
#ifdef USE_LRU_OPTIONAL
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace LRU {
|
||||
namespace Internal {
|
||||
|
||||
// A roll-your-own replacement of `std::optional`.
|
||||
//
|
||||
// This class is only to be used if `std::optional` is unavailable. It
|
||||
// implements an optional type simply on top of a `unique_ptr`. It is
|
||||
// API-compatible with `std::optional`, as required for our purposes.
|
||||
template <typename T>
|
||||
class Optional {
|
||||
public:
|
||||
/// Constructor.
|
||||
Optional() = default;
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
/// \param other The other optional object to copy from.
|
||||
Optional(const Optional& other) {
|
||||
if (other) emplace(*other);
|
||||
}
|
||||
|
||||
/// Generalized copy constructor.
|
||||
///
|
||||
/// \param other The other optional object to copy from.
|
||||
template <typename U,
|
||||
typename = std::enable_if_t<std::is_convertible<T, U>::value>>
|
||||
Optional(const Optional<U>& other) {
|
||||
if (other) emplace(*other);
|
||||
}
|
||||
|
||||
/// Move constructor.
|
||||
///
|
||||
/// \param other The other optional object to move into this one.
|
||||
Optional(Optional&& other) noexcept {
|
||||
swap(other);
|
||||
}
|
||||
|
||||
/// Generalized move constructor.
|
||||
///
|
||||
/// \param other The other optional object to move into this one.
|
||||
template <typename U,
|
||||
typename = std::enable_if_t<std::is_convertible<T, U>::value>>
|
||||
Optional(Optional<U>&& other) noexcept {
|
||||
if (other) {
|
||||
_value = std::make_unique<T>(std::move(*other));
|
||||
}
|
||||
}
|
||||
|
||||
/// Assignment operator.
|
||||
///
|
||||
/// \param other The other object to assign from.
|
||||
/// \returns The resulting optional instance.
|
||||
Optional& operator=(Optional other) noexcept {
|
||||
swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Swaps the contents of this optional with another one.
|
||||
///
|
||||
/// \param other The other optional to swap with.
|
||||
void swap(Optional& other) {
|
||||
_value.swap(other._value);
|
||||
}
|
||||
|
||||
/// Swaps the contents of two optionals.
|
||||
///
|
||||
/// \param first The first optional to swap.
|
||||
/// \param second The second optional to swap.
|
||||
friend void swap(Optional& first, Optional& second) /* NOLINT */ {
|
||||
first.swap(second);
|
||||
}
|
||||
|
||||
/// \returns True if the `Optional` has a value, else false.
|
||||
bool has_value() const noexcept {
|
||||
return static_cast<bool>(_value);
|
||||
}
|
||||
|
||||
/// \copydoc has_value()
|
||||
explicit operator bool() const noexcept {
|
||||
return has_value();
|
||||
}
|
||||
|
||||
/// \returns A pointer to the current value. Behavior is undefined if the
|
||||
/// optional has no value.
|
||||
T* operator->() {
|
||||
return _value.get();
|
||||
}
|
||||
|
||||
/// \returns A const pointer to the current value. Behavior is undefined if
|
||||
/// the `Optional` has no value.
|
||||
const T* operator->() const {
|
||||
return _value.get();
|
||||
}
|
||||
|
||||
/// \returns A const reference to the current value. Behavior is undefined if
|
||||
/// the `Optional` has no value.
|
||||
const T& operator*() const {
|
||||
return *_value;
|
||||
}
|
||||
|
||||
/// \returns A reference to the current value. Behavior is undefined if
|
||||
/// the `Optional` has no value.
|
||||
T& operator*() {
|
||||
return *_value;
|
||||
}
|
||||
|
||||
/// \returns A reference to the current value.
|
||||
/// \throws std::runtime_error If the `Optional` currently has no value.
|
||||
T& value() {
|
||||
if (!has_value()) {
|
||||
// Actually std::bad_optional_access
|
||||
throw std::runtime_error("optional has no value");
|
||||
}
|
||||
|
||||
return *_value;
|
||||
}
|
||||
|
||||
/// \returns A const reference to the current value.
|
||||
/// \throws std::runtime_error If the `Optional` currently has no value.
|
||||
const T& value() const {
|
||||
if (!has_value()) {
|
||||
// Actually std::bad_optional_access
|
||||
throw std::runtime_error("optional has no value");
|
||||
}
|
||||
|
||||
return *_value;
|
||||
}
|
||||
|
||||
/// \returns The current value, or the given argument if there is no value.
|
||||
/// \param default_value The value to return if this `Optional` currently has
|
||||
/// no value.
|
||||
template <class U>
|
||||
T value_or(U&& default_value) const {
|
||||
return *this ? **this : static_cast<T>(std::forward<U>(default_value));
|
||||
}
|
||||
|
||||
/// Resets the `Optional` to have no value.
|
||||
void reset() noexcept {
|
||||
_value.reset();
|
||||
}
|
||||
|
||||
/// Constructs the `Optional`'s value with the given arguments.
|
||||
///
|
||||
/// \param args Arguments to perfeclty forward to the value's constructor.
|
||||
template <typename... Args>
|
||||
void emplace(Args&&... args) {
|
||||
_value = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename>
|
||||
friend class Optional;
|
||||
|
||||
/// The value, as we implement it.
|
||||
std::unique_ptr<T> _value;
|
||||
};
|
||||
} // namespace Internal
|
||||
} // namespace LRU
|
||||
|
||||
#endif
|
||||
|
||||
#endif // LRU_INTERNAL_OPTIONAL_HPP
|
||||
150
src/3rdParty/lru-cache/include/lru/internal/statistics-mutator.hpp
vendored
Normal file
150
src/3rdParty/lru-cache/include/lru/internal/statistics-mutator.hpp
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef LRU_STATISTICS_MUTATOR_HPP
|
||||
#define LRU_STATISTICS_MUTATOR_HPP
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include <lru/internal/optional.hpp>
|
||||
#include <lru/statistics.hpp>
|
||||
|
||||
namespace LRU {
|
||||
namespace Internal {
|
||||
|
||||
/// A mutable proxy interface to a statistics object.
|
||||
///
|
||||
/// The `StatisticsMutator` allows modification of the members of a statistics
|
||||
/// object via a narrow interface, available only to internal classes. The point
|
||||
/// of this is that while we don't want the user to be able to modify the hit or
|
||||
/// miss count on a statistics object (it is "getter-only" in that sense), it's
|
||||
/// also not ideal, from an encapsulation standpoint, to make the cache classes
|
||||
/// (which do need to access and modify the hit and miss counts) friends of the
|
||||
/// statistics. This is especially true since the caches should only need to
|
||||
/// register hits or misses and not have to increment the count of total
|
||||
/// accesses. As such, we really require a "package-level" interface that is not
|
||||
/// visible to the end user, while at the same time providing an interface to
|
||||
/// internal classes. The `StatisticsMutator` is a proxy/adapter class that
|
||||
/// serves exactly this purpose. It is friends with the `Statistics` and can
|
||||
/// thus access its members. At the same time the interface it defines is narrow
|
||||
/// and provides only the necessary interface for the cache classes to register
|
||||
/// hits and misses.
|
||||
template <typename Key>
|
||||
class StatisticsMutator {
|
||||
public:
|
||||
using StatisticsPointer = std::shared_ptr<Statistics<Key>>;
|
||||
|
||||
/// Constructor.
|
||||
StatisticsMutator() noexcept = default;
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param stats A shared pointer lvalue reference.
|
||||
StatisticsMutator(const StatisticsPointer& stats) // NOLINT(runtime/explicit)
|
||||
: _stats(stats) {
|
||||
}
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param stats A shared pointer rvalue reference to move into the
|
||||
/// mutator.
|
||||
StatisticsMutator(StatisticsPointer&& stats) // NOLINT(runtime/explicit)
|
||||
: _stats(std::move(stats)) {
|
||||
}
|
||||
|
||||
/// Registers a hit for the given key with the internal statistics.
|
||||
///
|
||||
/// \param key The key to register a hit for.
|
||||
void register_hit(const Key& key) {
|
||||
assert(has_stats());
|
||||
|
||||
_stats->_total_accesses += 1;
|
||||
_stats->_total_hits += 1;
|
||||
|
||||
auto iterator = _stats->_key_map.find(key);
|
||||
if (iterator != _stats->_key_map.end()) {
|
||||
iterator->second.hits += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// Registers a miss for the given key with the internal statistics.
|
||||
///
|
||||
/// \param key The key to register a miss for.
|
||||
void register_miss(const Key& key) {
|
||||
assert(has_stats());
|
||||
|
||||
_stats->_total_accesses += 1;
|
||||
|
||||
auto iterator = _stats->_key_map.find(key);
|
||||
if (iterator != _stats->_key_map.end()) {
|
||||
iterator->second.misses += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// \returns A reference to the statistics object.
|
||||
Statistics<Key>& get() noexcept {
|
||||
assert(has_stats());
|
||||
return *_stats;
|
||||
}
|
||||
|
||||
/// \returns A const reference to the statistics object.
|
||||
const Statistics<Key>& get() const noexcept {
|
||||
assert(has_stats());
|
||||
return *_stats;
|
||||
}
|
||||
|
||||
/// \returns A `shared_ptr` to the statistics object.
|
||||
StatisticsPointer& shared() noexcept {
|
||||
return _stats;
|
||||
}
|
||||
|
||||
/// \returns A const `shared_ptr` to the statistics object.
|
||||
const StatisticsPointer& shared() const noexcept {
|
||||
return _stats;
|
||||
}
|
||||
|
||||
/// \returns True if the mutator has a statistics object, else false.
|
||||
bool has_stats() const noexcept {
|
||||
return _stats != nullptr;
|
||||
}
|
||||
|
||||
/// \copydoc has_stats()
|
||||
explicit operator bool() const noexcept {
|
||||
return has_stats();
|
||||
}
|
||||
|
||||
/// Resets the internal statistics pointer.
|
||||
void reset() {
|
||||
_stats.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
/// A shared pointer to a statistics object.
|
||||
std::shared_ptr<Statistics<Key>> _stats;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace LRU
|
||||
|
||||
#endif // LRU_STATISTICS_MUTATOR_HPP
|
||||
116
src/3rdParty/lru-cache/include/lru/internal/timed-information.hpp
vendored
Normal file
116
src/3rdParty/lru-cache/include/lru/internal/timed-information.hpp
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef LRU_INTERNAL_TIMED_INFORMATION_HPP
|
||||
#define LRU_INTERNAL_TIMED_INFORMATION_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include <lru/internal/definitions.hpp>
|
||||
#include <lru/internal/information.hpp>
|
||||
#include <lru/internal/utility.hpp>
|
||||
|
||||
namespace LRU {
|
||||
namespace Internal {
|
||||
|
||||
/// The information object for timed caches.
|
||||
///
|
||||
/// TimedInformation differs from plain information only in that it stores the
|
||||
/// creation time, to know when a key has expired.
|
||||
///
|
||||
/// \tparam Key The key type of the information.
|
||||
/// \tparam Value The value type of the information.
|
||||
template <typename Key, typename Value>
|
||||
struct TimedInformation : public Information<Key, Value> {
|
||||
using super = Information<Key, Value>;
|
||||
using typename super::QueueIterator;
|
||||
using Timestamp = Internal::Timestamp;
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param value_ The value for the information.
|
||||
/// \param insertion_time_ The insertion timestamp of the key.
|
||||
/// \param order_ The order iterator for the information.
|
||||
TimedInformation(const Value& value_,
|
||||
const Timestamp& insertion_time_,
|
||||
QueueIterator order_ = QueueIterator())
|
||||
: super(value_, order_), insertion_time(insertion_time_) {
|
||||
}
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// Uses the current time as the insertion timestamp.
|
||||
///
|
||||
/// \param value_ The value for the information.
|
||||
/// \param order_ The order iterator for the information.
|
||||
explicit TimedInformation(const Value& value_,
|
||||
QueueIterator order_ = QueueIterator())
|
||||
: TimedInformation(value_, Internal::Clock::now(), order_) {
|
||||
}
|
||||
|
||||
/// \copydoc Information::Information(QueueIterator,ValueArguments&&)
|
||||
template <typename... ValueArguments>
|
||||
TimedInformation(QueueIterator order_, ValueArguments&&... value_argument)
|
||||
: super(std::forward<ValueArguments>(value_argument)..., order_)
|
||||
, insertion_time(Internal::Clock::now()) {
|
||||
}
|
||||
|
||||
/// \copydoc Information::Information(QueueIterator,const
|
||||
/// std::tuple<ValueArguments...>&)
|
||||
template <typename... ValueArguments>
|
||||
explicit TimedInformation(
|
||||
const std::tuple<ValueArguments...>& value_arguments,
|
||||
QueueIterator order_ = QueueIterator())
|
||||
: super(value_arguments, order_), insertion_time(Internal::Clock::now()) {
|
||||
}
|
||||
|
||||
/// Compares this timed information for equality with another one.
|
||||
///
|
||||
/// Additionally to key and value equality, the timed information requires
|
||||
/// that the insertion timestamps be equal.
|
||||
///
|
||||
/// \param other The other timed information.
|
||||
/// \returns True if this information equals the other one, else false.
|
||||
bool operator==(const TimedInformation& other) const noexcept {
|
||||
if (super::operator!=(other)) return false;
|
||||
return this->insertion_time == other.insertion_time;
|
||||
}
|
||||
|
||||
/// Compares this timed information for inequality with another one.
|
||||
///
|
||||
/// \param other The other timed information.
|
||||
/// \returns True if this information does not equal the other one, else
|
||||
/// false.
|
||||
/// \see operator==()
|
||||
bool operator!=(const TimedInformation& other) const noexcept {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
/// The time at which the key of the information was insterted into a cache.
|
||||
const Timestamp insertion_time;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace LRU
|
||||
|
||||
#endif // LRU_INTERNAL_TIMED_INFORMATION_HPP
|
||||
178
src/3rdParty/lru-cache/include/lru/internal/utility.hpp
vendored
Normal file
178
src/3rdParty/lru-cache/include/lru/internal/utility.hpp
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
/// The MIT License (MIT)
|
||||
/// Copyright (c) 2016 Peter Goldsborough
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to
|
||||
/// deal in the Software without restriction, including without limitation the
|
||||
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
/// sell copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
/// IN THE SOFTWARE.
|
||||
|
||||
#ifndef LRU_UTILITY_HPP
|
||||
#define LRU_UTILITY_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace LRU {
|
||||
namespace Internal {
|
||||
|
||||
/// Generates an index sequence for a tuple.
|
||||
///
|
||||
/// \tparam Ts The types of the tuple (to deduce the size).
|
||||
template <typename... Ts>
|
||||
constexpr auto tuple_indices(const std::tuple<Ts...>&) {
|
||||
return std::make_index_sequence<sizeof...(Ts)>();
|
||||
}
|
||||
|
||||
/// Applies (in the functional sense) a tuple to the constructor of a class.
|
||||
///
|
||||
/// \tparam T The type to construct.
|
||||
/// \tparam Indices The indices into the tuple (generated from an index
|
||||
/// sequence).
|
||||
/// \param args The tuple of arguments to construct the object with.
|
||||
template <typename T, typename... Args, std::size_t... Indices>
|
||||
constexpr T construct_from_tuple(const std::tuple<Args...>& arguments,
|
||||
std::index_sequence<Indices...>) {
|
||||
return T(std::forward<Args>(std::get<Indices>(arguments))...);
|
||||
}
|
||||
|
||||
/// Applies (in the functional sense) a tuple to the constructor of a class.
|
||||
///
|
||||
/// \tparam T The type to construct.
|
||||
/// \param args The tuple of arguments to construct the object with.
|
||||
template <typename T, typename... Args>
|
||||
constexpr T construct_from_tuple(const std::tuple<Args...>& args) {
|
||||
return construct_from_tuple<T>(args, tuple_indices(args));
|
||||
}
|
||||
|
||||
/// Applies (in the functional sense) a tuple to the constructor of a class.
|
||||
///
|
||||
/// \tparam T The type to construct.
|
||||
/// \param args The tuple of arguments to construct the object with.
|
||||
template <typename T, typename... Args>
|
||||
constexpr T construct_from_tuple(std::tuple<Args...>&& args) {
|
||||
return construct_from_tuple<T>(std::move(args), tuple_indices(args));
|
||||
}
|
||||
|
||||
/// A type trait that disables a template overload if a type is not an iterator.
|
||||
///
|
||||
/// \tparam T the type to check.
|
||||
template <typename T>
|
||||
using enable_if_iterator = typename std::iterator_traits<T>::value_type;
|
||||
|
||||
/// A type trait that disables a template overload if a type is not a range.
|
||||
///
|
||||
/// \tparam T the type to check.
|
||||
template <typename T>
|
||||
using enable_if_range = std::pair<decltype(std::declval<T>().begin()),
|
||||
decltype(std::declval<T>().end())>;
|
||||
|
||||
/// A type trait that disables a template overload if a type is not an iterator
|
||||
/// over a pair.
|
||||
///
|
||||
/// \tparam T the type to check.
|
||||
template <typename T>
|
||||
using enable_if_iterator_over_pair =
|
||||
std::pair<typename std::iterator_traits<T>::value_type::first_type,
|
||||
typename std::iterator_traits<T>::value_type::first_type>;
|
||||
|
||||
|
||||
/// A type trait that disables a template overload if a type is not convertible
|
||||
/// to a target type.
|
||||
///
|
||||
/// \tparam Target The type one wants to check against.
|
||||
/// \tparam T The type to check.
|
||||
template <typename Target, typename T>
|
||||
using enable_if_same = std::enable_if_t<std::is_convertible<T, Target>::value>;
|
||||
|
||||
/// Base case for `static_all_of` (the neutral element of AND is true).
|
||||
constexpr bool static_all_of() noexcept {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Checks if all the given parameters evaluate to true.
|
||||
///
|
||||
/// \param head The first expression to check.
|
||||
/// \param tail The remaining expression to check.
|
||||
template <typename Head, typename... Tail>
|
||||
constexpr bool static_all_of(Head&& head, Tail&&... tail) {
|
||||
// Replace with (ts && ...) when the time is right
|
||||
return std::forward<Head>(head) && static_all_of(std::forward<Tail>(tail)...);
|
||||
}
|
||||
|
||||
/// Base case for `static_any_of` (the neutral element of OR is false).
|
||||
constexpr bool static_any_of() noexcept {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Checks if any the given parameters evaluate to true.
|
||||
///
|
||||
/// \param head The first expression to check.
|
||||
/// \param tail The remaining expression to check.
|
||||
/// \returns True if any of the given parameters evaluate to true.
|
||||
template <typename Head, typename... Tail>
|
||||
constexpr bool static_any_of(Head&& head, Tail&&... tail) {
|
||||
// Replace with (ts || ...) when the time is right
|
||||
return std::forward<Head>(head) || static_any_of(std::forward<Tail>(tail)...);
|
||||
}
|
||||
|
||||
/// Checks if none the given parameters evaluate to true.
|
||||
///
|
||||
/// \param ts The expressions to check.
|
||||
/// \returns True if any of the given parameters evaluate to true.
|
||||
template <typename... Ts>
|
||||
constexpr bool static_none_of(Ts&&... ts) {
|
||||
// Replace with (!ts && ...) when the time is right
|
||||
return !static_any_of(std::forward<Ts>(ts)...);
|
||||
}
|
||||
|
||||
/// Checks if all the given types are convertible to the first type.
|
||||
///
|
||||
/// \tparam T the first type.
|
||||
/// \tparam Ts The types to check against the first.
|
||||
template <typename T, typename... Ts>
|
||||
constexpr bool
|
||||
all_of_type = static_all_of(std::is_convertible<Ts, T>::value...);
|
||||
|
||||
/// Checks if none of the given types are convertible to the first type.
|
||||
///
|
||||
/// \tparam T the first type.
|
||||
/// \tparam Ts The types to check against the first.
|
||||
template <typename T, typename... Ts>
|
||||
constexpr bool
|
||||
none_of_type = static_none_of(std::is_convertible<Ts, T>::value...);
|
||||
|
||||
/// Base case for `for_each`.
|
||||
template <typename Function>
|
||||
void for_each(Function) noexcept {
|
||||
}
|
||||
|
||||
/// Calls a function for each of the given variadic arguments.
|
||||
///
|
||||
/// \param function The function to call for each argument.
|
||||
/// \param head The first value to call the function with.
|
||||
/// \param tail The remaining values to call the function with.
|
||||
template <typename Function, typename Head, typename... Tail>
|
||||
void for_each(Function function, Head&& head, Tail&&... tail) {
|
||||
function(std::forward<Head>(head));
|
||||
for_each(function, std::forward<Tail>(tail)...);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace LRU
|
||||
|
||||
#endif // LRU_UTILITY_HPP
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user