mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-07-11 09:44:17 +02:00
Compare commits
298 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0beb18c9e1 | |||
| ade5762a45 | |||
| 5cb7abf10c | |||
| 7561f7ef70 | |||
| ac69bb2142 | |||
| 2c7c8e19e2 | |||
| 59d00a0134 | |||
| 372fadfb99 | |||
| 406c2c0bbf | |||
| a5ba35ce92 | |||
| f6b2887ae0 | |||
| cba474000e | |||
| cb64246288 | |||
| 4006be49f8 | |||
| 085f1dcb68 | |||
| 1372d71fa7 | |||
| 2fda2d512d | |||
| 1edc304453 | |||
| a291936bf8 | |||
| 9b343bae3e | |||
| 6336cc82e8 | |||
| 3450e3c238 | |||
| 49017c4813 | |||
| 27a88dd333 | |||
| 6f4f6cf7de | |||
| 0020cac123 | |||
| 1160758a81 | |||
| 5c205d6287 | |||
| e814408026 | |||
| 46e85c4586 | |||
| f4b16a8762 | |||
| cdc8201222 | |||
| 94c10ca9f9 | |||
| 724155ba91 | |||
| 6ffa916336 | |||
| e3badc754d | |||
| df9783f41f | |||
| e9c6d51566 | |||
| a8c8223f69 | |||
| 9b3f827991 | |||
| 2d2bfd64ff | |||
| 73a825cbb1 | |||
| 3e0e72e50c | |||
| 259350c974 | |||
| e14b4475ff | |||
| b4f030cd37 | |||
| f28c488ecf | |||
| 2ac22f8dd9 | |||
| 5e0b92f1b4 | |||
| e1e35982e4 | |||
| 1356f282d0 | |||
| 7e8e0d4744 | |||
| 56b20a3a13 | |||
| 10cdacfa30 | |||
| 81a20150f2 | |||
| 5e5ea642b0 | |||
| e7733a2d43 | |||
| 3e60e46ae4 | |||
| 194037bd4e | |||
| 5037be3d8f | |||
| 8aca0fe288 | |||
| 0e667a9b0f | |||
| 12940f2e1b | |||
| faf6c04dee | |||
| 6aadbc18a9 | |||
| 2be34a6938 | |||
| daa0d2d3c4 | |||
| 1b4af9deef | |||
| db6cb43336 | |||
| 012d352fa7 | |||
| 904096cd6e | |||
| b3bb67b43a | |||
| deba43640e | |||
| d665efdc3a | |||
| 66493c8dd1 | |||
| 9ff85a620e | |||
| ae1ee7cc3d | |||
| 2392cf7014 | |||
| 08fe525a3b | |||
| 1cd30601ed | |||
| 07713e97d7 | |||
| be307f3eb9 | |||
| d9bfdc3fcd | |||
| 064a96dfd2 | |||
| 428e035032 | |||
| 2db9cd0437 | |||
| bd78c33f11 | |||
| f16774357a | |||
| 00868a1b29 | |||
| 93212882d0 | |||
| 7f1ab4043c | |||
| 65822ecf86 | |||
| 9dff4f2005 | |||
| ec8f3b0414 | |||
| dde3c73af7 | |||
| bc80ea92a3 | |||
| 497dc14d11 | |||
| c80866ab5c | |||
| d856f3f5bd | |||
| 5d811f03f4 | |||
| 600a8b468b | |||
| e0c5e861be | |||
| d049c395fc | |||
| 6aed46c603 | |||
| f0723a6ec9 | |||
| bc624524cf | |||
| d1a44cdae8 | |||
| 8a46f9e6ca | |||
| eba66a2bb3 | |||
| 7ea5234049 | |||
| 0b5c37e1c5 | |||
| 2f7be602c8 | |||
| 05289e80a0 | |||
| 1ddc283ea2 | |||
| f969b0d4c7 | |||
| 1bd475cfab | |||
| f678788b6c | |||
| 379371f0b5 | |||
| 247511fd38 | |||
| 8de55a1937 | |||
| 73010de3b5 | |||
| b29496eb8e | |||
| dc88ed97ab | |||
| 10d2e5dd40 | |||
| f357fad0ff | |||
| 1ae55e8615 | |||
| 012120c344 | |||
| e3565eb924 | |||
| cd9fe1630b | |||
| f5524bab1b | |||
| 471a7203a5 | |||
| 456c062246 | |||
| 2c0bb98cac | |||
| bf4670c855 | |||
| 6113f9bcb4 | |||
| fe919d18b2 | |||
| d0687dd631 | |||
| 1bf53e6432 | |||
| 58a4f1e5e9 | |||
| ea304becf6 | |||
| b0a7d6994b | |||
| bd522e2385 | |||
| 27e9accffa | |||
| 4f41366600 | |||
| d26701c004 | |||
| d7983d81e3 | |||
| 2e122c3255 | |||
| eef1f837a2 | |||
| e52d8f70ba | |||
| d4cf5a998c | |||
| 608922dc41 | |||
| 438937ace3 | |||
| 50605bd0e9 | |||
| c1d46b1866 | |||
| e47b32b2e6 | |||
| f0dc40ac15 | |||
| 15a502cf36 | |||
| a1152f5313 | |||
| 68150c7448 | |||
| 71fe1b809c | |||
| ec6901b93d | |||
| 3c7eb2ac88 | |||
| baecf73f4b | |||
| 9a2561d9cf | |||
| 14db91f756 | |||
| 99df8cacbf | |||
| f576962dd8 | |||
| 6284a5de4f | |||
| 7a84cd3db7 | |||
| bfcb409e3b | |||
| 40a5f1a13d | |||
| 9fb889a85b | |||
| 2116ca16be | |||
| 0de9c67a9a | |||
| eb7f9beec8 | |||
| 3a2bdc5def | |||
| bb3937cd69 | |||
| 337daf7ed9 | |||
| 2696e304e2 | |||
| 8d936b3c67 | |||
| 1275a9ebaf | |||
| 3104fc20da | |||
| 4dd0121576 | |||
| 96a6cfbf6f | |||
| 22cdc36aff | |||
| f5b33d376b | |||
| 1683d36702 | |||
| 6794bae8da | |||
| f50ad3b63e | |||
| 3b527d4511 | |||
| 1b479d2a5e | |||
| 23783f77e2 | |||
| ce44032f1a | |||
| 379c5d761e | |||
| 0197b56451 | |||
| f25283e397 | |||
| f10228a1e1 | |||
| b25211fd0a | |||
| d178c451d8 | |||
| b37d5754eb | |||
| 15723f3483 | |||
| 91b5102c8c | |||
| 462b77c3ff | |||
| 2f3006a572 | |||
| 2c69d31eae | |||
| bc46bef230 | |||
| 408a25daef | |||
| bf7bff181c | |||
| b7d2b1a26c | |||
| dadf043e8c | |||
| 7cf43515bb | |||
| 1dea7c48e7 | |||
| 98439f7b1f | |||
| 821bb9ec05 | |||
| ac26a0836c | |||
| 75fa8f2bdd | |||
| 0a49e52fce | |||
| 76a0cf525c | |||
| b7fa45ee76 | |||
| b8ab8b69bd | |||
| 647b2b1cbd | |||
| b97f652e3f | |||
| 3eb2a2693f | |||
| 18fecfbd07 | |||
| e8ba3653ee | |||
| 848a9fd551 | |||
| 0cb16dee70 | |||
| 24090772cd | |||
| 62c40f1f01 | |||
| e5c580a1d4 | |||
| ad4bab8f68 | |||
| c16c1b76ed | |||
| 763d005f06 | |||
| b26b0996e3 | |||
| 23b931c5c6 | |||
| 31f621681d | |||
| 581e21a5f7 | |||
| aa04e57df5 | |||
| 99a8afac8d | |||
| 16fde28c39 | |||
| ed515782f9 | |||
| fa85ef3f92 | |||
| 12136217c4 | |||
| 0e5445d2a7 | |||
| e83a343bab | |||
| d5aeb9e20a | |||
| d9128872fd | |||
| 6e129a69d2 | |||
| 6e2d17073a | |||
| f622726bb1 | |||
| a39a0fd268 | |||
| f14e061438 | |||
| 0356b8a73e | |||
| 1d9b7c0387 | |||
| 2164078b2d | |||
| aeb1d500df | |||
| e44a388455 | |||
| 74044cdbce | |||
| 3f6ec596f0 | |||
| 1831d11671 | |||
| 362e89d668 | |||
| 936836e096 | |||
| 0e9de44c72 | |||
| d3841591a5 | |||
| 7f13863bb8 | |||
| dab29f8443 | |||
| 73d11a88da | |||
| 21320c750b | |||
| 35ce3c483f | |||
| fdd360f919 | |||
| fcb1d4ff4e | |||
| 815a59b6ed | |||
| 2097ff232c | |||
| 53d98a53e8 | |||
| f81a95f3a9 | |||
| 74e190511b | |||
| a86f441ac8 | |||
| 2557c2e887 | |||
| 6accade0d5 | |||
| 9437e1ac41 | |||
| b2b87f9e87 | |||
| f2ab17ff94 | |||
| a1514e2c6c | |||
| 329c6d42be | |||
| 800da09b1d | |||
| fb8c1b901d | |||
| df817924e0 | |||
| c227686d46 | |||
| 683ced4fe2 | |||
| ad6a8a5cf3 | |||
| 20e3896714 | |||
| 084df36598 | |||
| 28abbc6bf5 | |||
| 3a125a2d7a | |||
| 8415a4b0d6 | |||
| 209e676e3a | |||
| a64431c7b5 | |||
| 665eb3d6b3 |
@@ -0,0 +1,23 @@
|
||||
name: 'Commit Message Check'
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- reopened
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
check-commit-message:
|
||||
name: Check Commit Message
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check for a commit prefix
|
||||
uses: gsactions/commit-message-checker@16fa2d5de096ae0d35626443bcd24f1e756cafee
|
||||
with:
|
||||
accessToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
pattern: '^[A-Z0-9][A-Za-z0-9 \["\/\\]+:.+'
|
||||
excludeTitle: true
|
||||
excludeDescription: true
|
||||
checkAllCommitMessages: true
|
||||
error: 'Commit messages should be capitalized, start with a prefix, delimited by a colon. Example: "Debugger: Add a paste bytes option to the memory view"'
|
||||
@@ -0,0 +1,21 @@
|
||||
name: 🧹 Clean Up Old Caches
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *" # Every day at 12am UTC.
|
||||
workflow_dispatch: # As well as manually.
|
||||
|
||||
jobs:
|
||||
clean:
|
||||
name: "Clean Up Caches"
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: write
|
||||
steps:
|
||||
- name: Clean Caches
|
||||
uses: PCSX2/cache-clean-action@v1.1.0
|
||||
with:
|
||||
items: '[{"key": " deps", "count": 4}, {"key": " ccache", "count": 1}, {"key": " flatpak", "count": 1}]'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: all
|
||||
on_failure: error
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
run: ./.github/workflows/scripts/common/update_base_translation.sh
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0
|
||||
with:
|
||||
title: "Qt: Update Base Translation"
|
||||
commit-message: "[ci skip] Qt: Update Base Translation."
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
mv ./game_controller_db.txt ${{github.workspace}}/bin/resources/game_controller_db.txt
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0
|
||||
with:
|
||||
title: "PAD: Update to latest controller database"
|
||||
commit-message: "[ci skip] PAD: Update to latest controller database."
|
||||
|
||||
@@ -153,7 +153,7 @@ jobs:
|
||||
mv "./${{ steps.artifact-metadata.outputs.artifact-name }}.flatpak" "$GITHUB_WORKSPACE"/ci-artifacts/
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
|
||||
path: ci-artifacts
|
||||
|
||||
@@ -27,10 +27,6 @@ on:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
detail:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
patchesUrl:
|
||||
required: false
|
||||
type: string
|
||||
@@ -95,8 +91,8 @@ jobs:
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .ccache
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} ${{ inputs.detail }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
|
||||
restore-keys: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} ${{ inputs.detail }} ccache
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
|
||||
restore-keys: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} ccache
|
||||
|
||||
- name: Install Packages
|
||||
run: |
|
||||
@@ -174,7 +170,7 @@ jobs:
|
||||
|
||||
- name: Upload artifact
|
||||
if: inputs.buildAppImage == true
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
|
||||
path: ci-artifacts
|
||||
|
||||
@@ -13,6 +13,10 @@ on:
|
||||
required: false
|
||||
type: string
|
||||
default: macos-26
|
||||
arch:
|
||||
required: false
|
||||
type: string
|
||||
default: x86-64
|
||||
patchesUrl:
|
||||
required: false
|
||||
type: string
|
||||
@@ -62,11 +66,15 @@ jobs:
|
||||
echo "#define DEFAULT_UPDATER_CHANNEL \"stable\"" > ./pcsx2-qt/DefaultUpdaterChannel.h
|
||||
cat ./pcsx2-qt/DefaultUpdaterChannel.h
|
||||
|
||||
- name: Use Xcode 26.0.1
|
||||
run: sudo xcode-select -s /Applications/Xcode_26.0.1.app
|
||||
- name: Use Xcode 26.2
|
||||
run: sudo xcode-select -s /Applications/Xcode_26.2.app
|
||||
|
||||
- name: Install Metal Toolchain
|
||||
run: xcodebuild -downloadComponent MetalToolchain
|
||||
run: |
|
||||
for i in {1..5}; do
|
||||
if xcrun metal -v; then break; fi
|
||||
xcodebuild -downloadComponent MetalToolchain
|
||||
done
|
||||
|
||||
- name: Prepare Artifact Metadata
|
||||
id: artifact-metadata
|
||||
@@ -94,12 +102,12 @@ jobs:
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/deps
|
||||
key: ${{ inputs.os }} deps ${{ hashFiles('.github/workflows/scripts/macos/*', '.github/workflows/scripts/common/*.patch') }}
|
||||
key: ${{ inputs.os }} ${{ inputs.arch }} deps ${{ hashFiles('.github/workflows/scripts/macos/*', '.github/workflows/scripts/common/*.patch') }}
|
||||
|
||||
- name: Build Dependencies
|
||||
if: steps.cache-deps.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
.github/workflows/scripts/macos/build-dependencies.sh "$HOME/deps"
|
||||
.github/workflows/scripts/macos/build-dependencies${{ case(inputs.arch == 'x86-64', '', '-universal') }}.sh "$HOME/deps"
|
||||
|
||||
- name: Download patches
|
||||
run: |
|
||||
@@ -115,16 +123,16 @@ jobs:
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .ccache
|
||||
key: ${{ inputs.os }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
|
||||
restore-keys: ${{ inputs.os }} ccache
|
||||
key: ${{ inputs.os }} ${{ inputs.arch }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
|
||||
restore-keys: ${{ inputs.os }} ${{ inputs.arch }} ccache
|
||||
|
||||
- name: Generate CMake Files
|
||||
run: |
|
||||
cmake -DCMAKE_PREFIX_PATH="$HOME/deps" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_OSX_ARCHITECTURES="x86_64" \
|
||||
-DCMAKE_OSX_ARCHITECTURES="${{ case(inputs.arch == 'x86-64', 'x86_64', inputs.arch) }}" \
|
||||
-DDISABLE_ADVANCE_SIMD=ON \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=${{ case(inputs.arch == 'x86-64', 'ON', 'OFF') }} \
|
||||
-DUSE_LINKED_FFMPEG=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
@@ -147,6 +155,11 @@ jobs:
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Build GSRunner
|
||||
if: inputs.arch != 'x86-64'
|
||||
working-directory: build
|
||||
run: make -j$(getconf _NPROCESSORS_ONLN) pcsx2-gsrunner
|
||||
|
||||
- name: Run Tests
|
||||
working-directory: build
|
||||
run: make -j$(getconf _NPROCESSORS_ONLN) unittests
|
||||
@@ -184,6 +197,7 @@ jobs:
|
||||
app_store_connect_api_key_json_file: 'key.json'
|
||||
|
||||
- name: Zip Build Artifacts
|
||||
if: inputs.arch == 'x86-64'
|
||||
run: |
|
||||
TAG="$(git tag --points-at HEAD)"
|
||||
if [ -z "$TAG" ]; then
|
||||
@@ -197,7 +211,8 @@ jobs:
|
||||
cp "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.xz" ci-artifacts/macOS.tar.xz
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
if: inputs.arch == 'x86-64'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
|
||||
path: "*.tar.xz"
|
||||
|
||||
@@ -18,3 +18,12 @@ jobs:
|
||||
artifactPrefixName: "PCSX2-macos-Qt"
|
||||
sign_and_notarize: true # If we find that notarization takes a long time we should disable that on PR builds
|
||||
secrets: inherit
|
||||
build_macos_qt_arm:
|
||||
name: "arm64"
|
||||
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
|
||||
uses: ./.github/workflows/macos_build.yml
|
||||
with:
|
||||
jobName: "MacOS arm64 Build"
|
||||
artifactPrefixName: "PCSX2-macos-Qt-arm64"
|
||||
arch: arm64
|
||||
secrets: inherit
|
||||
|
||||
@@ -68,7 +68,7 @@ jobs:
|
||||
mv ./release-notes.md ${GITHUB_WORKSPACE}/release-notes.md
|
||||
|
||||
- name: Create a GitHub Release (Manual)
|
||||
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b
|
||||
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe
|
||||
if: steps.tag_version.outputs.new_tag && github.event_name == 'workflow_dispatch'
|
||||
with:
|
||||
body_path: ./release-notes.md
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
tag_name: ${{ steps.tag_version.outputs.new_tag }}
|
||||
|
||||
- name: Create a GitHub Release (Push)
|
||||
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b
|
||||
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe
|
||||
if: steps.tag_version.outputs.new_tag && github.event_name != 'workflow_dispatch'
|
||||
with:
|
||||
body_path: ./release-notes.md
|
||||
@@ -151,6 +151,19 @@ jobs:
|
||||
sign_and_notarize: true
|
||||
secrets: inherit
|
||||
|
||||
# We don't use the artifacts, but we need this for the cache it generates
|
||||
build_macos_qt_arm:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
needs:
|
||||
- cut-release
|
||||
name: "MacOS"
|
||||
uses: ./.github/workflows/macos_build.yml
|
||||
with:
|
||||
jobName: "Generate arm64 Caches"
|
||||
artifactPrefixName: "PCSX2-macos-Qt-arm64"
|
||||
arch: arm64
|
||||
secrets: inherit
|
||||
|
||||
# Upload the Artifacts
|
||||
upload_artifacts:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
@@ -168,7 +181,7 @@ jobs:
|
||||
- name: Prepare Artifact Folder
|
||||
run: mkdir ./ci-artifacts/
|
||||
|
||||
- uses: actions/download-artifact@v7
|
||||
- uses: actions/download-artifact@v8
|
||||
name: Download all Artifacts
|
||||
with:
|
||||
path: ./ci-artifacts/
|
||||
|
||||
@@ -1,16 +1,3 @@
|
||||
diff --git a/CHANGES b/CHANGES
|
||||
index 5d3dd16..587b612 100644
|
||||
--- a/CHANGES
|
||||
+++ b/CHANGES
|
||||
@@ -4,7 +4,7 @@ v2024.1
|
||||
- Update dependencies
|
||||
- Propagate test/install options to Glslang
|
||||
|
||||
-v2024.0
|
||||
+v2024.0 2024-03-09
|
||||
- Update dependencies
|
||||
- Utilities:
|
||||
- Use Python3 explicitly in utility scripts
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index ffcb54b..7c1a6d8 100644
|
||||
--- a/CMakeLists.txt
|
||||
|
||||
@@ -18,94 +18,102 @@ if [ "${INSTALLDIR:0:1}" != "/" ]; then
|
||||
INSTALLDIR="$PWD/$INSTALLDIR"
|
||||
fi
|
||||
|
||||
QT=6.11.0
|
||||
QTAPNG=1.3.0
|
||||
|
||||
FFMPEG=8.0
|
||||
FREETYPE=2.14.1
|
||||
HARFBUZZ=12.2.0
|
||||
HARFBUZZ=13.0.0
|
||||
LIBBACKTRACE=ad106d5fdd5d960bd33fae1c48a351af567fd075
|
||||
LIBJPEGTURBO=3.1.2
|
||||
LIBPNG=1.6.53
|
||||
LIBJPEGTURBO=3.1.3
|
||||
LIBPNG=1.6.55
|
||||
LIBWEBP=1.6.0
|
||||
NVENC=13.0.19.0
|
||||
SDL=SDL3-3.4.0
|
||||
QT=6.10.1
|
||||
QTAPNG=1.3.0
|
||||
SDL=SDL3-3.4.2
|
||||
LZ4=1.10.0
|
||||
VULKAN=1.4.328.1
|
||||
ZSTD=1.5.7
|
||||
KDDOCKWIDGETS=2.4.0
|
||||
PLUTOVG=1.3.2
|
||||
PLUTOSVG=0.0.7
|
||||
RAPIDYAML=0.11.1
|
||||
|
||||
SHADERC=2025.4
|
||||
SHADERC_GLSLANG=7a47e2531cb334982b2a2dd8513dca0a3de4373d
|
||||
SHADERC_SPIRVHEADERS=b824a462d4256d720bebb40e78b9eb8f78bbb305
|
||||
SHADERC_SPIRVTOOLS=971a7b6e8d7740035bbff089bbbf9f42951ecfd5
|
||||
SHADERC=2026.1
|
||||
SHADERC_GLSLANG=f0bd0257c308b9a26562c1a30c4748a0219cc951
|
||||
SHADERC_SPIRVHEADERS=04f10f650d514df88b76d25e83db360142c7b174
|
||||
SHADERC_SPIRVTOOLS=fbe4f3ad913c44fe8700545f8ffe35d1382b7093
|
||||
|
||||
mkdir -p deps-build
|
||||
cd deps-build
|
||||
|
||||
export PKG_CONFIG_PATH="$INSTALLDIR/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
|
||||
cat > SHASUMS <<EOF
|
||||
grep . > SHASUMS <<EOF
|
||||
231ad85979864d914dc9568a1b71c91d6cf20d7b2021d059103bf0eb51cb755e qtbase-everywhere-src-$QT.tar.xz
|
||||
d3adb02ac5e2fe24068dbdaee0d7cc68cc3fa8553291c1bfce77c9fe8e940cc8 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
dfa8d653be07087d9407ed4a4ebae847f8953e0b7abd829f089803ab652a30e6 qtsvg-everywhere-src-$QT.tar.xz
|
||||
cfb1993d7a10848965b01b9cf33a54b8a4ba4e5e3a6d28d59483e73f10d9fc76 qttools-everywhere-src-$QT.tar.xz
|
||||
54f48b2fe4316892ff930195f170a5385644acc7393505f3155c066b8e1ffe56 qttranslations-everywhere-src-$QT.tar.xz
|
||||
e710e6e760f92922b86e4dd68f6bbe94ef6510919519d1b0068e874b5ad84d37 qtwayland-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
|
||||
b2751fccb6cc4c77708113cd78b561059b6fa904b24162fa0be2d60273d27b8e ffmpeg-$FFMPEG.tar.xz
|
||||
32427e8c471ac095853212a37aef816c60b42052d4d9e48230bab3bdf2936ccc freetype-$FREETYPE.tar.xz
|
||||
f63fc519f150465bd0bdafcdf3d0e9c23474f4c474171cd515ea1b3a72c081fb harfbuzz-$HARFBUZZ.tar.gz
|
||||
fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.zip
|
||||
8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
1d3fb8ccc2932d04aa3663e22ef5ef490244370f4e568d7850165068778d98d4 libpng-$LIBPNG.tar.xz
|
||||
207f96964dc9475b13c1f66565bf145d2658089d65b4cf786d351da2857fc269 harfbuzz-$HARFBUZZ.tar.gz
|
||||
96e5c2d7f2c482a60d5804da48a2eb9a0db0719b2c65dcc169fbfdcf37f3a45d libbacktrace-$LIBBACKTRACE.tar.gz
|
||||
075920b826834ac4ddf97661cc73491047855859affd671d52079c6867c1c6c0 libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
d925722864837ad5ae2a82070d4b2e0603dc72af44bd457c3962298258b8e82d libpng-$LIBPNG.tar.xz
|
||||
e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWEBP.tar.gz
|
||||
082cbf5f429e0d80820f68dc2b507a94d4cc1b4e70817b119bbb8ec6a69584b8 $SDL.tar.gz
|
||||
452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c libpng-$LIBPNG-apng.patch.gz
|
||||
ef39a2e3f9a8a78296c40da701967dd1b0d0d6e267e483863ce70f8a03b4050c $SDL.tar.gz
|
||||
017c06f75ffed25f6cda9b5369ec6da0ac35a6616adf7abe4222516a0237f37a libpng-$LIBPNG-apng.patch.gz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
13da39edb3a40ed9713ae390ca89faa2f1202c9dda869ef306a8d4383e242bee nv-codec-headers-$NVENC.tar.gz
|
||||
c465aa56757e7746ac707f582b6e2d51546569a4a2488c1172fb543aa5fdfc2c vulkan-sdk-$VULKAN.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
5a6226f7e23db51fdc3223121eba53f3f5447cf0cc4d6cb82a3a2df7a65d265d qtbase-everywhere-src-$QT.tar.xz
|
||||
498eabdf2381db96f808942b3e3c765f6360fe6c0e9961f0a45ff7a4c68d7a72 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
c02f355a58f3bbcf404a628bf488b6aeb2d84a94c269afdb86f6e529343ab01f qtsvg-everywhere-src-$QT.tar.xz
|
||||
8148408380ffea03101a26305c812b612ea30dbc07121e58707601522404d49b qttools-everywhere-src-$QT.tar.xz
|
||||
8e49a2df88a12c376a479ae7bd272a91cf57ebb4e7c0cf7341b3565df99d2314 qttranslations-everywhere-src-$QT.tar.xz
|
||||
49bf6db800227a6b2c971f4c5d03dd1e81297e7ffb296ce4a96437304f27cb13 qtwayland-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
8a89fb6612ace8954470aae004623374a8fc8b7a34a4277bee5527173b064faf shaderc-$SHADERC.tar.gz
|
||||
272d2725b140e09e85b96eecdc59c2e00c1a14cda2301767e1bf3c363a44b931 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
c693867f10a7760ef1bcf85419d51783586768cc2c601d03841bc6a8b2554b9c shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
06b0a042f2e121e954badb4fd78c9e2d4bc7ed6087eceb26ab559c23cf94334f shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
51dbf24fe72e43dd7cb9a289d3cab47112010f1a2ed69b6fc8ac0dff31991ed2 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
7bd4e79ce18b1d47517e7e91fbb7cf19d4f01942804a519bc7c0bf32b6325dd5 plutovg-$PLUTOVG.tar.gz
|
||||
78561b571ac224030cdc450ca2986b4de915c2ba7616004a6d71a379bffd15f3 plutosvg-$PLUTOSVG.tar.gz
|
||||
9d9938269adc25e9a9b84650338b87d130cf469d82685fffc028c325279619c1 rapidyaml-$RAPIDYAML-src.tgz
|
||||
|
||||
245002feccbe7f8361b223545a5654cea69780745886872d7efff50a38d96c66 shaderc-$SHADERC.tar.gz
|
||||
bd58dca4dac67dcf7640292d7d63e0416274d40ee2200f7301878cec11ac6647 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
1b220e3eec1714f0451b0e3652979bd280edf10893f617837b88e6359a804ded shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
cabb35f4eef0da3ef72ad9edd596af4191d7507a8f35c05df526d2d5ff889f59 shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
EOF
|
||||
|
||||
curl -L \
|
||||
-o "freetype-$FREETYPE.tar.xz" "https://sourceforge.net/projects/freetype/files/freetype2/$FREETYPE/freetype-$FREETYPE.tar.xz/download" \
|
||||
-o "harfbuzz-$HARFBUZZ.tar.gz" "https://github.com/harfbuzz/harfbuzz/archive/refs/tags/$HARFBUZZ.tar.gz" \
|
||||
-O "https://github.com/ianlancetaylor/libbacktrace/archive/$LIBBACKTRACE.zip" \
|
||||
-O "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/$LIBJPEGTURBO/libjpeg-turbo-$LIBJPEGTURBO.tar.gz" \
|
||||
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
|
||||
-O "https://download.sourceforge.net/libpng-apng/libpng-$LIBPNG-apng.patch.gz" \
|
||||
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/releases/download/v$LZ4/lz4-$LZ4.tar.gz" \
|
||||
-O "https://libsdl.org/release/$SDL.tar.gz" \
|
||||
-O "https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz" \
|
||||
-O "https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/vulkan-sdk-$VULKAN.tar.gz" \
|
||||
-O "https://github.com/FFmpeg/nv-codec-headers/releases/download/n$NVENC/nv-codec-headers-$NVENC.tar.gz" \
|
||||
-O "https://ffmpeg.org/releases/ffmpeg-$FFMPEG.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtwayland-everywhere-src-$QT.tar.xz" \
|
||||
-o "QtApng-$QTAPNG.tar.gz" "https://github.com/jurplel/QtApng/archive/refs/tags/$QTAPNG.tar.gz" \
|
||||
-o "shaderc-$SHADERC.tar.gz" "https://github.com/google/shaderc/archive/refs/tags/v$SHADERC.tar.gz" \
|
||||
-o "shaderc-glslang-$SHADERC_GLSLANG.tar.gz" "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG.tar.gz" \
|
||||
-o "shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS.tar.gz" \
|
||||
-o "shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS.tar.gz" \
|
||||
-o "KDDockWidgets-$KDDOCKWIDGETS.tar.gz" "https://github.com/KDAB/KDDockWidgets/archive/v$KDDOCKWIDGETS.tar.gz" \
|
||||
-o "plutovg-$PLUTOVG.tar.gz" "https://github.com/sammycage/plutovg/archive/v$PLUTOVG.tar.gz" \
|
||||
-o "plutosvg-$PLUTOSVG.tar.gz" "https://github.com/sammycage/plutosvg/archive/v$PLUTOSVG.tar.gz"
|
||||
if ! shasum -sa 256 --check SHASUMS 2> /dev/null; then
|
||||
curl -L \
|
||||
-O "https://sourceforge.net/projects/freetype/files/freetype2/$FREETYPE/freetype-$FREETYPE.tar.xz" \
|
||||
-O "https://github.com/harfbuzz/harfbuzz/archive/$HARFBUZZ/harfbuzz-$HARFBUZZ.tar.gz" \
|
||||
-O "https://github.com/ianlancetaylor/libbacktrace/archive/$LIBBACKTRACE/libbacktrace-$LIBBACKTRACE.tar.gz" \
|
||||
-O "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/$LIBJPEGTURBO/libjpeg-turbo-$LIBJPEGTURBO.tar.gz" \
|
||||
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
|
||||
-O "https://download.sourceforge.net/libpng-apng/libpng-$LIBPNG-apng.patch.gz" \
|
||||
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/releases/download/v$LZ4/lz4-$LZ4.tar.gz" \
|
||||
-O "https://libsdl.org/release/$SDL.tar.gz" \
|
||||
-O "https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz" \
|
||||
-O "https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/vulkan-sdk-$VULKAN.tar.gz" \
|
||||
-O "https://github.com/FFmpeg/nv-codec-headers/releases/download/n$NVENC/nv-codec-headers-$NVENC.tar.gz" \
|
||||
-O "https://ffmpeg.org/releases/ffmpeg-$FFMPEG.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtwayland-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://github.com/jurplel/QtApng/archive/$QTAPNG/QtApng-$QTAPNG.tar.gz" \
|
||||
-O "https://github.com/google/shaderc/archive/v$SHADERC/shaderc-$SHADERC.tar.gz" \
|
||||
-O "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG/shaderc-glslang-$SHADERC_GLSLANG.tar.gz" \
|
||||
-O "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS/shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" \
|
||||
-O "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS/shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" \
|
||||
-O "https://github.com/KDAB/KDDockWidgets/archive/v$KDDOCKWIDGETS/KDDockWidgets-$KDDOCKWIDGETS.tar.gz" \
|
||||
-O "https://github.com/sammycage/plutovg/archive/v$PLUTOVG/plutovg-$PLUTOVG.tar.gz" \
|
||||
-O "https://github.com/sammycage/plutosvg/archive/v$PLUTOSVG/plutosvg-$PLUTOSVG.tar.gz" \
|
||||
-O "https://github.com/biojppm/rapidyaml/releases/download/v$RAPIDYAML/rapidyaml-$RAPIDYAML-src.tgz"
|
||||
fi
|
||||
|
||||
shasum -a 256 --check SHASUMS
|
||||
shasum -a 256 --check --strict SHASUMS
|
||||
|
||||
if [ "$BUILD_FFMPEG" -ne 0 ]; then
|
||||
echo "Installing vulkan headers..."
|
||||
@@ -140,9 +148,9 @@ fi
|
||||
|
||||
echo "Building libbacktrace..."
|
||||
rm -fr "libbacktrace-$LIBBACKTRACE"
|
||||
unzip "$LIBBACKTRACE.zip"
|
||||
tar xf "libbacktrace-$LIBBACKTRACE.tar.gz"
|
||||
cd "libbacktrace-$LIBBACKTRACE"
|
||||
./configure --prefix="$INSTALLDIR"
|
||||
./configure --prefix="$INSTALLDIR" --with-pic
|
||||
make
|
||||
make install
|
||||
cd ..
|
||||
@@ -213,7 +221,7 @@ tar xf "harfbuzz-$HARFBUZZ.tar.gz"
|
||||
cd "harfbuzz-$HARFBUZZ"
|
||||
# Add an SOVERSION to match system harfbuzz
|
||||
sed -i 's/PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)/PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE SOVERSION 0)/g' CMakeLists.txt
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DHB_BUILD_UTILS=OFF -DHB_HAVE_FREETYPE=ON -DHB_HAVE_GOBJECT=ON -B build -G Ninja
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DHB_BUILD_UTILS=OFF -DHB_HAVE_FREETYPE=ON -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
@@ -247,7 +255,7 @@ tar xf "qtbase-everywhere-src-$QT.tar.xz"
|
||||
cd "qtbase-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
../configure -prefix "$INSTALLDIR" -release -dbus-linked -gui -widgets -fontconfig -qt-doubleconversion -ssl -openssl-runtime -opengl desktop -qpa xcb,wayland -xkbcommon -xcb -gtk -- --log-level=STATUS -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DFEATURE_dbus=ON -DFEATURE_icu=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON
|
||||
../configure -prefix "$INSTALLDIR" -release -dbus-linked -gui -widgets -fontconfig -qt-doubleconversion -ssl -openssl-runtime -opengl desktop -qpa xcb,wayland -xkbcommon -xcb -- --log-level=STATUS -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DFEATURE_dbus=ON -DFEATURE_icu=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON -DFEATURE_gtk3=OFF
|
||||
cmake --build . --parallel
|
||||
ninja install
|
||||
cd ../../
|
||||
@@ -344,6 +352,15 @@ cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building RapidYAML..."
|
||||
rm -fr "rapidyaml-$RAPIDYAML-src"
|
||||
tar xf "rapidyaml-$RAPIDYAML-src.tgz"
|
||||
cd "rapidyaml-$RAPIDYAML-src"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building shaderc..."
|
||||
rm -fr "shaderc-$SHADERC"
|
||||
tar xf "shaderc-$SHADERC.tar.gz"
|
||||
|
||||
@@ -24,6 +24,7 @@ LZ4=1.10.0
|
||||
ZSTD=1.5.7
|
||||
PLUTOVG=1.3.2
|
||||
PLUTOSVG=0.0.7
|
||||
RAPIDYAML=0.11.1
|
||||
|
||||
SHADERC=2025.4
|
||||
SHADERC_GLSLANG=7a47e2531cb334982b2a2dd8513dca0a3de4373d
|
||||
@@ -33,10 +34,10 @@ SHADERC_SPIRVTOOLS=971a7b6e8d7740035bbff089bbbf9f42951ecfd5
|
||||
mkdir -p deps-build
|
||||
cd deps-build
|
||||
|
||||
cat > SHASUMS <<EOF
|
||||
grep . > SHASUMS <<EOF
|
||||
32427e8c471ac095853212a37aef816c60b42052d4d9e48230bab3bdf2936ccc freetype-$FREETYPE.tar.xz
|
||||
f63fc519f150465bd0bdafcdf3d0e9c23474f4c474171cd515ea1b3a72c081fb harfbuzz-$HARFBUZZ.tar.gz
|
||||
fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.zip
|
||||
96e5c2d7f2c482a60d5804da48a2eb9a0db0719b2c65dcc169fbfdcf37f3a45d libbacktrace-$LIBBACKTRACE.tar.gz
|
||||
a050a892d3b4a7bb010c3a95c7301e49656d72a64f1fc709a90b8aded192bed2 libpng-$LIBPNG.tar.xz
|
||||
e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWEBP.tar.gz
|
||||
dad488474a51a0b01d547cd2834893d6299328d2e30f479a3564088b5476bae2 $SDL.tar.gz
|
||||
@@ -49,30 +50,34 @@ c693867f10a7760ef1bcf85419d51783586768cc2c601d03841bc6a8b2554b9c shaderc-spirv-
|
||||
06b0a042f2e121e954badb4fd78c9e2d4bc7ed6087eceb26ab559c23cf94334f shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
7bd4e79ce18b1d47517e7e91fbb7cf19d4f01942804a519bc7c0bf32b6325dd5 plutovg-$PLUTOVG.tar.gz
|
||||
78561b571ac224030cdc450ca2986b4de915c2ba7616004a6d71a379bffd15f3 plutosvg-$PLUTOSVG.tar.gz
|
||||
9d9938269adc25e9a9b84650338b87d130cf469d82685fffc028c325279619c1 rapidyaml-$RAPIDYAML-src.tgz
|
||||
EOF
|
||||
|
||||
curl -L \
|
||||
-o "freetype-$FREETYPE.tar.xz" "https://sourceforge.net/projects/freetype/files/freetype2/$FREETYPE/freetype-$FREETYPE.tar.xz/download" \
|
||||
-o "harfbuzz-$HARFBUZZ.tar.gz" "https://github.com/harfbuzz/harfbuzz/archive/refs/tags/$HARFBUZZ.tar.gz" \
|
||||
-O "https://github.com/ianlancetaylor/libbacktrace/archive/$LIBBACKTRACE.zip" \
|
||||
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
|
||||
-O "https://download.sourceforge.net/libpng-apng/libpng-$LIBPNG-apng.patch.gz" \
|
||||
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/releases/download/v$LZ4/lz4-$LZ4.tar.gz" \
|
||||
-O "https://libsdl.org/release/$SDL.tar.gz" \
|
||||
-O "https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz" \
|
||||
-o "shaderc-$SHADERC.tar.gz" "https://github.com/google/shaderc/archive/refs/tags/v$SHADERC.tar.gz" \
|
||||
-o "shaderc-glslang-$SHADERC_GLSLANG.tar.gz" "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG.tar.gz" \
|
||||
-o "shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS.tar.gz" \
|
||||
-o "shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS.tar.gz" \
|
||||
-o "plutovg-$PLUTOVG.tar.gz" "https://github.com/sammycage/plutovg/archive/v$PLUTOVG.tar.gz" \
|
||||
-o "plutosvg-$PLUTOSVG.tar.gz" "https://github.com/sammycage/plutosvg/archive/v$PLUTOSVG.tar.gz"
|
||||
if ! shasum -sa 256 --check SHASUMS 2> /dev/null; then
|
||||
curl -L \
|
||||
-O "https://sourceforge.net/projects/freetype/files/freetype2/$FREETYPE/freetype-$FREETYPE.tar.xz" \
|
||||
-O "https://github.com/harfbuzz/harfbuzz/archive/$HARFBUZZ/harfbuzz-$HARFBUZZ.tar.gz" \
|
||||
-O "https://github.com/ianlancetaylor/libbacktrace/archive/$LIBBACKTRACE/libbacktrace-$LIBBACKTRACE.tar.gz" \
|
||||
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
|
||||
-O "https://download.sourceforge.net/libpng-apng/libpng-$LIBPNG-apng.patch.gz" \
|
||||
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/releases/download/v$LZ4/lz4-$LZ4.tar.gz" \
|
||||
-O "https://libsdl.org/release/$SDL.tar.gz" \
|
||||
-O "https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz" \
|
||||
-O "https://github.com/google/shaderc/archive/v$SHADERC/shaderc-$SHADERC.tar.gz" \
|
||||
-O "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG/shaderc-glslang-$SHADERC_GLSLANG.tar.gz" \
|
||||
-O "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS/shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" \
|
||||
-O "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS/shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" \
|
||||
-O "https://github.com/sammycage/plutovg/archive/v$PLUTOVG/plutovg-$PLUTOVG.tar.gz" \
|
||||
-O "https://github.com/sammycage/plutosvg/archive/v$PLUTOSVG/plutosvg-$PLUTOSVG.tar.gz" \
|
||||
-O "https://github.com/biojppm/rapidyaml/releases/download/v$RAPIDYAML/rapidyaml-$RAPIDYAML-src.tgz"
|
||||
fi
|
||||
|
||||
shasum -a 256 --check SHASUMS
|
||||
shasum -a 256 --check --strict SHASUMS
|
||||
|
||||
echo "Building libbacktrace..."
|
||||
rm -fr "libbacktrace-$LIBBACKTRACE"
|
||||
unzip "$LIBBACKTRACE.zip"
|
||||
tar xf "libbacktrace-$LIBBACKTRACE.tar.gz"
|
||||
cd "libbacktrace-$LIBBACKTRACE"
|
||||
./configure --prefix="$INSTALLDIR"
|
||||
make
|
||||
@@ -173,6 +178,15 @@ cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building RapidYAML..."
|
||||
rm -fr "rapidyaml-$RAPIDYAML-src"
|
||||
tar xf "rapidyaml-$RAPIDYAML-src.tgz"
|
||||
cd "rapidyaml-$RAPIDYAML-src"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building shaderc..."
|
||||
rm -fr "shaderc-$SHADERC"
|
||||
tar xf "shaderc-$SHADERC.tar.gz"
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://libsdl.org/release/SDL3-3.4.0.tar.gz",
|
||||
"sha256": "082cbf5f429e0d80820f68dc2b507a94d4cc1b4e70817b119bbb8ec6a69584b8"
|
||||
"url": "https://libsdl.org/release/SDL3-3.4.2.tar.gz",
|
||||
"sha256": "ef39a2e3f9a8a78296c40da701967dd1b0d0d6e267e483863ce70f8a03b4050c"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
|
||||
@@ -15,24 +15,24 @@
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/google/shaderc.git",
|
||||
"commit": "73743588fe9c39f2f1c780a087d94afac691a189"
|
||||
"commit": "301b4ede53d59b68bf55f95bb26412d9233c8187"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/KhronosGroup/glslang/archive/7a47e2531cb334982b2a2dd8513dca0a3de4373d.tar.gz",
|
||||
"sha256": "272d2725b140e09e85b96eecdc59c2e00c1a14cda2301767e1bf3c363a44b931",
|
||||
"url": "https://github.com/KhronosGroup/glslang/archive/f0bd0257c308b9a26562c1a30c4748a0219cc951.tar.gz",
|
||||
"sha256": "bd58dca4dac67dcf7640292d7d63e0416274d40ee2200f7301878cec11ac6647",
|
||||
"dest": "third_party/glslang"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/KhronosGroup/SPIRV-Headers/archive/b824a462d4256d720bebb40e78b9eb8f78bbb305.tar.gz",
|
||||
"sha256": "c693867f10a7760ef1bcf85419d51783586768cc2c601d03841bc6a8b2554b9c",
|
||||
"url": "https://github.com/KhronosGroup/SPIRV-Headers/archive/04f10f650d514df88b76d25e83db360142c7b174.tar.gz",
|
||||
"sha256": "1b220e3eec1714f0451b0e3652979bd280edf10893f617837b88e6359a804ded",
|
||||
"dest": "third_party/spirv-headers"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/KhronosGroup/SPIRV-Tools/archive/971a7b6e8d7740035bbff089bbbf9f42951ecfd5.tar.gz",
|
||||
"sha256": "06b0a042f2e121e954badb4fd78c9e2d4bc7ed6087eceb26ab559c23cf94334f",
|
||||
"url": "https://github.com/KhronosGroup/SPIRV-Tools/archive/fbe4f3ad913c44fe8700545f8ffe35d1382b7093.tar.gz",
|
||||
"sha256": "cabb35f4eef0da3ef72ad9edd596af4191d7507a8f35c05df526d2d5ff889f59",
|
||||
"dest": "third_party/spirv-tools"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -14,21 +14,21 @@
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://downloads.sourceforge.net/project/libpng/libpng16/1.6.53/libpng-1.6.53.tar.xz",
|
||||
"sha256": "1d3fb8ccc2932d04aa3663e22ef5ef490244370f4e568d7850165068778d98d4"
|
||||
"url": "https://downloads.sourceforge.net/project/libpng/libpng16/1.6.55/libpng-1.6.55.tar.xz",
|
||||
"sha256": "d925722864837ad5ae2a82070d4b2e0603dc72af44bd457c3962298258b8e82d"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://download.sourceforge.net/libpng-apng/libpng-1.6.53-apng.patch.gz",
|
||||
"dest-filename": "libpng-1.6.53-apng.patch.gz",
|
||||
"sha256": "452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c"
|
||||
"url": "https://download.sourceforge.net/libpng-apng/libpng-1.6.55-apng.patch.gz",
|
||||
"dest-filename": "libpng-1.6.55-apng.patch.gz",
|
||||
"sha256": "017c06f75ffed25f6cda9b5369ec6da0ac35a6616adf7abe4222516a0237f37a"
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"commands":
|
||||
[
|
||||
"gunzip -f libpng-1.6.53-apng.patch.gz",
|
||||
"patch -p1 < \"libpng-1.6.53-apng.patch\""
|
||||
"gunzip -f libpng-1.6.55-apng.patch.gz",
|
||||
"patch -p1 < \"libpng-1.6.55-apng.patch\""
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "rapidyaml",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"-DBUILD_SHARED_LIBS=ON"
|
||||
],
|
||||
"build-options": {
|
||||
"strip": true
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/biojppm/rapidyaml.git",
|
||||
"tag": "v0.11.1",
|
||||
"commit": "119b6042064d3828819e428e32e5a0f3035d5643"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"/lib/cmake"
|
||||
]
|
||||
}
|
||||
@@ -35,6 +35,7 @@
|
||||
"modules/25-plutosvg.json",
|
||||
"modules/26-libpng.json",
|
||||
"modules/27-qtapng.json",
|
||||
"modules/28-rapidyaml.json",
|
||||
{
|
||||
"name": "pcsx2",
|
||||
"buildsystem": "cmake-ninja",
|
||||
@@ -79,4 +80,3 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -7,16 +7,21 @@ merge_binaries() {
|
||||
ARMDIR=$2
|
||||
echo "Merging ARM64 binaries from $ARMDIR into fat binaries at $X86DIR..."
|
||||
|
||||
IFS="
|
||||
"
|
||||
IFS=$'\n'
|
||||
FILES=()
|
||||
|
||||
pushd "$X86DIR"
|
||||
for X86BIN in $(find . -type f \( -name '*.dylib' -o -name '*.a' -o -perm +111 \)); do
|
||||
if file "$X86DIR/$X86BIN" | grep "Mach-O.*x86_64" >/dev/null; then
|
||||
ARMBIN="${ARMDIR}/${X86BIN}"
|
||||
echo "Merge $ARMBIN to $X86BIN..."
|
||||
lipo -create "$X86BIN" "$ARMBIN" -o "$X86BIN"
|
||||
FILES+=("$X86BIN")
|
||||
fi
|
||||
done
|
||||
# If the timestamps of all the files we touched aren't equal, make may recreate them on make install if one depends on another
|
||||
# Minimize the chance of that by touching them all at once
|
||||
touch "${FILES[@]}"
|
||||
popd
|
||||
}
|
||||
|
||||
@@ -38,26 +43,28 @@ if [ "${INSTALLDIR:0:1}" != "/" ]; then
|
||||
INSTALLDIR="$PWD/$INSTALLDIR"
|
||||
fi
|
||||
|
||||
QT=6.11.0
|
||||
QTAPNG=1.3.0
|
||||
|
||||
FREETYPE=2.14.1
|
||||
HARFBUZZ=12.2.0
|
||||
SDL=SDL3-3.4.0
|
||||
HARFBUZZ=13.0.0
|
||||
SDL=SDL3-3.4.2
|
||||
ZSTD=1.5.7
|
||||
LZ4=1.10.0
|
||||
LIBPNG=1.6.53
|
||||
LIBJPEGTURBO=3.1.2
|
||||
LIBPNG=1.6.55
|
||||
LIBJPEGTURBO=3.1.3
|
||||
LIBWEBP=1.6.0
|
||||
FFMPEG=8.0
|
||||
MOLTENVK=1.4.1
|
||||
QT=6.10.1
|
||||
QTAPNG=1.3.0
|
||||
KDDOCKWIDGETS=2.4.0
|
||||
PLUTOVG=1.3.2
|
||||
PLUTOSVG=0.0.7
|
||||
RAPIDYAML=0.11.1
|
||||
|
||||
SHADERC=2025.4
|
||||
SHADERC_GLSLANG=7a47e2531cb334982b2a2dd8513dca0a3de4373d
|
||||
SHADERC_SPIRVHEADERS=b824a462d4256d720bebb40e78b9eb8f78bbb305
|
||||
SHADERC_SPIRVTOOLS=971a7b6e8d7740035bbff089bbbf9f42951ecfd5
|
||||
SHADERC=2026.1
|
||||
SHADERC_GLSLANG=f0bd0257c308b9a26562c1a30c4748a0219cc951
|
||||
SHADERC_SPIRVHEADERS=04f10f650d514df88b76d25e83db360142c7b174
|
||||
SHADERC_SPIRVTOOLS=fbe4f3ad913c44fe8700545f8ffe35d1382b7093
|
||||
|
||||
mkdir -p deps-build
|
||||
cd deps-build
|
||||
@@ -77,60 +84,66 @@ CMAKE_ARCH_X64=-DCMAKE_OSX_ARCHITECTURES="x86_64"
|
||||
CMAKE_ARCH_ARM64=-DCMAKE_OSX_ARCHITECTURES="arm64"
|
||||
CMAKE_ARCH_UNIVERSAL=-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
|
||||
|
||||
cat > SHASUMS <<EOF
|
||||
grep . > SHASUMS <<EOF
|
||||
231ad85979864d914dc9568a1b71c91d6cf20d7b2021d059103bf0eb51cb755e qtbase-everywhere-src-$QT.tar.xz
|
||||
d3adb02ac5e2fe24068dbdaee0d7cc68cc3fa8553291c1bfce77c9fe8e940cc8 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
dfa8d653be07087d9407ed4a4ebae847f8953e0b7abd829f089803ab652a30e6 qtsvg-everywhere-src-$QT.tar.xz
|
||||
cfb1993d7a10848965b01b9cf33a54b8a4ba4e5e3a6d28d59483e73f10d9fc76 qttools-everywhere-src-$QT.tar.xz
|
||||
54f48b2fe4316892ff930195f170a5385644acc7393505f3155c066b8e1ffe56 qttranslations-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
|
||||
32427e8c471ac095853212a37aef816c60b42052d4d9e48230bab3bdf2936ccc freetype-$FREETYPE.tar.xz
|
||||
f63fc519f150465bd0bdafcdf3d0e9c23474f4c474171cd515ea1b3a72c081fb harfbuzz-$HARFBUZZ.tar.gz
|
||||
082cbf5f429e0d80820f68dc2b507a94d4cc1b4e70817b119bbb8ec6a69584b8 $SDL.tar.gz
|
||||
207f96964dc9475b13c1f66565bf145d2658089d65b4cf786d351da2857fc269 harfbuzz-$HARFBUZZ.tar.gz
|
||||
ef39a2e3f9a8a78296c40da701967dd1b0d0d6e267e483863ce70f8a03b4050c $SDL.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
1d3fb8ccc2932d04aa3663e22ef5ef490244370f4e568d7850165068778d98d4 libpng-$LIBPNG.tar.xz
|
||||
d925722864837ad5ae2a82070d4b2e0603dc72af44bd457c3962298258b8e82d libpng-$LIBPNG.tar.xz
|
||||
e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWEBP.tar.gz
|
||||
452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c libpng-$LIBPNG-apng.patch.gz
|
||||
8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
017c06f75ffed25f6cda9b5369ec6da0ac35a6616adf7abe4222516a0237f37a libpng-$LIBPNG-apng.patch.gz
|
||||
075920b826834ac4ddf97661cc73491047855859affd671d52079c6867c1c6c0 libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
b2751fccb6cc4c77708113cd78b561059b6fa904b24162fa0be2d60273d27b8e ffmpeg-$FFMPEG.tar.xz
|
||||
9985f141902a17de818e264d17c1ce334b748e499ee02fcb4703e4dc0038f89c v$MOLTENVK.tar.gz
|
||||
5a6226f7e23db51fdc3223121eba53f3f5447cf0cc4d6cb82a3a2df7a65d265d qtbase-everywhere-src-$QT.tar.xz
|
||||
498eabdf2381db96f808942b3e3c765f6360fe6c0e9961f0a45ff7a4c68d7a72 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
c02f355a58f3bbcf404a628bf488b6aeb2d84a94c269afdb86f6e529343ab01f qtsvg-everywhere-src-$QT.tar.xz
|
||||
8148408380ffea03101a26305c812b612ea30dbc07121e58707601522404d49b qttools-everywhere-src-$QT.tar.xz
|
||||
8e49a2df88a12c376a479ae7bd272a91cf57ebb4e7c0cf7341b3565df99d2314 qttranslations-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
8a89fb6612ace8954470aae004623374a8fc8b7a34a4277bee5527173b064faf shaderc-$SHADERC.tar.gz
|
||||
272d2725b140e09e85b96eecdc59c2e00c1a14cda2301767e1bf3c363a44b931 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
c693867f10a7760ef1bcf85419d51783586768cc2c601d03841bc6a8b2554b9c shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
06b0a042f2e121e954badb4fd78c9e2d4bc7ed6087eceb26ab559c23cf94334f shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
9985f141902a17de818e264d17c1ce334b748e499ee02fcb4703e4dc0038f89c MoltenVK-$MOLTENVK.tar.gz
|
||||
51dbf24fe72e43dd7cb9a289d3cab47112010f1a2ed69b6fc8ac0dff31991ed2 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
7bd4e79ce18b1d47517e7e91fbb7cf19d4f01942804a519bc7c0bf32b6325dd5 plutovg-$PLUTOVG.tar.gz
|
||||
78561b571ac224030cdc450ca2986b4de915c2ba7616004a6d71a379bffd15f3 plutosvg-$PLUTOSVG.tar.gz
|
||||
9d9938269adc25e9a9b84650338b87d130cf469d82685fffc028c325279619c1 rapidyaml-$RAPIDYAML-src.tgz
|
||||
|
||||
245002feccbe7f8361b223545a5654cea69780745886872d7efff50a38d96c66 shaderc-$SHADERC.tar.gz
|
||||
bd58dca4dac67dcf7640292d7d63e0416274d40ee2200f7301878cec11ac6647 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
1b220e3eec1714f0451b0e3652979bd280edf10893f617837b88e6359a804ded shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
cabb35f4eef0da3ef72ad9edd596af4191d7507a8f35c05df526d2d5ff889f59 shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
EOF
|
||||
|
||||
curl -C - -L \
|
||||
-o "freetype-$FREETYPE.tar.xz" "https://sourceforge.net/projects/freetype/files/freetype2/$FREETYPE/freetype-$FREETYPE.tar.xz/download" \
|
||||
-o "harfbuzz-$HARFBUZZ.tar.gz" "https://github.com/harfbuzz/harfbuzz/archive/refs/tags/$HARFBUZZ.tar.gz" \
|
||||
-O "https://libsdl.org/release/$SDL.tar.gz" \
|
||||
-O "https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/releases/download/v$LZ4/lz4-$LZ4.tar.gz" \
|
||||
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
|
||||
-O "https://download.sourceforge.net/libpng-apng/libpng-$LIBPNG-apng.patch.gz" \
|
||||
-O "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/$LIBJPEGTURBO/libjpeg-turbo-$LIBJPEGTURBO.tar.gz" \
|
||||
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
|
||||
-O "https://ffmpeg.org/releases/ffmpeg-$FFMPEG.tar.xz" \
|
||||
-O "https://github.com/KhronosGroup/MoltenVK/archive/refs/tags/v$MOLTENVK.tar.gz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
|
||||
-o "QtApng-$QTAPNG.tar.gz" "https://github.com/jurplel/QtApng/archive/refs/tags/$QTAPNG.tar.gz" \
|
||||
-o "shaderc-$SHADERC.tar.gz" "https://github.com/google/shaderc/archive/refs/tags/v$SHADERC.tar.gz" \
|
||||
-o "shaderc-glslang-$SHADERC_GLSLANG.tar.gz" "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG.tar.gz" \
|
||||
-o "shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS.tar.gz" \
|
||||
-o "shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS.tar.gz" \
|
||||
-o "KDDockWidgets-$KDDOCKWIDGETS.tar.gz" "https://github.com/KDAB/KDDockWidgets/archive/v$KDDOCKWIDGETS.tar.gz" \
|
||||
-o "plutovg-$PLUTOVG.tar.gz" "https://github.com/sammycage/plutovg/archive/v$PLUTOVG.tar.gz" \
|
||||
-o "plutosvg-$PLUTOSVG.tar.gz" "https://github.com/sammycage/plutosvg/archive/v$PLUTOSVG.tar.gz"
|
||||
if ! shasum -sa 256 --check SHASUMS 2> /dev/null; then
|
||||
curl -L \
|
||||
-O "https://sourceforge.net/projects/freetype/files/freetype2/$FREETYPE/freetype-$FREETYPE.tar.xz" \
|
||||
-O "https://github.com/harfbuzz/harfbuzz/archive/$HARFBUZZ/harfbuzz-$HARFBUZZ.tar.gz" \
|
||||
-O "https://libsdl.org/release/$SDL.tar.gz" \
|
||||
-O "https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/releases/download/v$LZ4/lz4-$LZ4.tar.gz" \
|
||||
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
|
||||
-O "https://download.sourceforge.net/libpng-apng/libpng-$LIBPNG-apng.patch.gz" \
|
||||
-O "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/$LIBJPEGTURBO/libjpeg-turbo-$LIBJPEGTURBO.tar.gz" \
|
||||
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
|
||||
-O "https://ffmpeg.org/releases/ffmpeg-$FFMPEG.tar.xz" \
|
||||
-O "https://github.com/KhronosGroup/MoltenVK/archive/v$MOLTENVK/MoltenVK-$MOLTENVK.tar.gz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://github.com/jurplel/QtApng/archive/$QTAPNG/QtApng-$QTAPNG.tar.gz" \
|
||||
-O "https://github.com/google/shaderc/archive/v$SHADERC/shaderc-$SHADERC.tar.gz" \
|
||||
-O "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG/shaderc-glslang-$SHADERC_GLSLANG.tar.gz" \
|
||||
-O "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS/shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" \
|
||||
-O "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS/shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" \
|
||||
-O "https://github.com/KDAB/KDDockWidgets/archive/v$KDDOCKWIDGETS/KDDockWidgets-$KDDOCKWIDGETS.tar.gz" \
|
||||
-O "https://github.com/sammycage/plutovg/archive/v$PLUTOVG/plutovg-$PLUTOVG.tar.gz" \
|
||||
-O "https://github.com/sammycage/plutosvg/archive/v$PLUTOSVG/plutosvg-$PLUTOSVG.tar.gz" \
|
||||
-O "https://github.com/biojppm/rapidyaml/releases/download/v$RAPIDYAML/rapidyaml-$RAPIDYAML-src.tgz"
|
||||
fi
|
||||
|
||||
shasum -a 256 --check SHASUMS
|
||||
shasum -a 256 --check --strict SHASUMS
|
||||
|
||||
echo "Installing SDL..."
|
||||
rm -fr "$SDL"
|
||||
@@ -150,7 +163,7 @@ if [ "$BUILD_FFMPEG" -ne 0 ]; then
|
||||
cd build
|
||||
LDFLAGS="-dead_strip $LDFLAGS" CFLAGS="-Os $CFLAGS" CXXFLAGS="-Os $CXXFLAGS" \
|
||||
../configure --prefix="$INSTALLDIR" \
|
||||
--enable-cross-compile --arch=x86_64 --cc='clang -arch x86_64' --cxx='clang++ -arch x86_64' --disable-x86asm \
|
||||
--enable-cross-compile --arch=x86_64 --cc='clang -arch x86_64' --cxx='clang++ -arch x86_64' \
|
||||
--disable-all --disable-autodetect --disable-static --enable-shared \
|
||||
--enable-avcodec --enable-avformat --enable-avutil --enable-swresample --enable-swscale \
|
||||
--enable-audiotoolbox --enable-videotoolbox \
|
||||
@@ -274,7 +287,7 @@ cd ..
|
||||
# MoltenVK already builds universal binaries, nothing special to do here.
|
||||
echo "Installing MoltenVK..."
|
||||
rm -fr "MoltenVK-${MOLTENVK}"
|
||||
tar xf "v$MOLTENVK.tar.gz"
|
||||
tar xf "MoltenVK-$MOLTENVK.tar.gz"
|
||||
cd "MoltenVK-${MOLTENVK}"
|
||||
./fetchDependencies --macos
|
||||
make macos MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=0 MVK_CONFIG_USE_METAL_PRIVATE_API=1
|
||||
@@ -417,6 +430,15 @@ make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building RapidYAML..."
|
||||
rm -fr "rapidyaml-$RAPIDYAML-src"
|
||||
tar xf "rapidyaml-$RAPIDYAML-src.tgz"
|
||||
cd "rapidyaml-$RAPIDYAML-src"
|
||||
cmake "${CMAKE_COMMON[@]}" -DBUILD_SHARED_LIBS=ON -B build
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
echo "Cleaning up..."
|
||||
cd ..
|
||||
rm -rf deps-build
|
||||
|
||||
@@ -20,26 +20,28 @@ if [ "${INSTALLDIR:0:1}" != "/" ]; then
|
||||
INSTALLDIR="$PWD/$INSTALLDIR"
|
||||
fi
|
||||
|
||||
QT=6.11.0
|
||||
QTAPNG=1.3.0
|
||||
|
||||
FREETYPE=2.14.1
|
||||
HARFBUZZ=12.2.0
|
||||
SDL=SDL3-3.4.0
|
||||
HARFBUZZ=13.0.0
|
||||
SDL=SDL3-3.4.2
|
||||
ZSTD=1.5.7
|
||||
LZ4=1.10.0
|
||||
LIBPNG=1.6.53
|
||||
LIBJPEGTURBO=3.1.2
|
||||
LIBPNG=1.6.55
|
||||
LIBJPEGTURBO=3.1.3
|
||||
LIBWEBP=1.6.0
|
||||
FFMPEG=8.0
|
||||
MOLTENVK=1.4.1
|
||||
QT=6.10.1
|
||||
QTAPNG=1.3.0
|
||||
KDDOCKWIDGETS=2.4.0
|
||||
PLUTOVG=1.3.2
|
||||
PLUTOSVG=0.0.7
|
||||
RAPIDYAML=0.11.1
|
||||
|
||||
SHADERC=2025.4
|
||||
SHADERC_GLSLANG=7a47e2531cb334982b2a2dd8513dca0a3de4373d
|
||||
SHADERC_SPIRVHEADERS=b824a462d4256d720bebb40e78b9eb8f78bbb305
|
||||
SHADERC_SPIRVTOOLS=971a7b6e8d7740035bbff089bbbf9f42951ecfd5
|
||||
SHADERC=2026.1
|
||||
SHADERC_GLSLANG=f0bd0257c308b9a26562c1a30c4748a0219cc951
|
||||
SHADERC_SPIRVHEADERS=04f10f650d514df88b76d25e83db360142c7b174
|
||||
SHADERC_SPIRVTOOLS=fbe4f3ad913c44fe8700545f8ffe35d1382b7093
|
||||
|
||||
mkdir -p deps-build
|
||||
cd deps-build
|
||||
@@ -58,60 +60,66 @@ CMAKE_COMMON=(
|
||||
-DCMAKE_INSTALL_NAME_DIR='$<INSTALL_PREFIX>/lib'
|
||||
)
|
||||
|
||||
cat > SHASUMS <<EOF
|
||||
grep . > SHASUMS <<EOF
|
||||
231ad85979864d914dc9568a1b71c91d6cf20d7b2021d059103bf0eb51cb755e qtbase-everywhere-src-$QT.tar.xz
|
||||
d3adb02ac5e2fe24068dbdaee0d7cc68cc3fa8553291c1bfce77c9fe8e940cc8 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
dfa8d653be07087d9407ed4a4ebae847f8953e0b7abd829f089803ab652a30e6 qtsvg-everywhere-src-$QT.tar.xz
|
||||
cfb1993d7a10848965b01b9cf33a54b8a4ba4e5e3a6d28d59483e73f10d9fc76 qttools-everywhere-src-$QT.tar.xz
|
||||
54f48b2fe4316892ff930195f170a5385644acc7393505f3155c066b8e1ffe56 qttranslations-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
|
||||
32427e8c471ac095853212a37aef816c60b42052d4d9e48230bab3bdf2936ccc freetype-$FREETYPE.tar.xz
|
||||
f63fc519f150465bd0bdafcdf3d0e9c23474f4c474171cd515ea1b3a72c081fb harfbuzz-$HARFBUZZ.tar.gz
|
||||
082cbf5f429e0d80820f68dc2b507a94d4cc1b4e70817b119bbb8ec6a69584b8 $SDL.tar.gz
|
||||
207f96964dc9475b13c1f66565bf145d2658089d65b4cf786d351da2857fc269 harfbuzz-$HARFBUZZ.tar.gz
|
||||
ef39a2e3f9a8a78296c40da701967dd1b0d0d6e267e483863ce70f8a03b4050c $SDL.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
1d3fb8ccc2932d04aa3663e22ef5ef490244370f4e568d7850165068778d98d4 libpng-$LIBPNG.tar.xz
|
||||
d925722864837ad5ae2a82070d4b2e0603dc72af44bd457c3962298258b8e82d libpng-$LIBPNG.tar.xz
|
||||
e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWEBP.tar.gz
|
||||
452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c libpng-$LIBPNG-apng.patch.gz
|
||||
8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
017c06f75ffed25f6cda9b5369ec6da0ac35a6616adf7abe4222516a0237f37a libpng-$LIBPNG-apng.patch.gz
|
||||
075920b826834ac4ddf97661cc73491047855859affd671d52079c6867c1c6c0 libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
b2751fccb6cc4c77708113cd78b561059b6fa904b24162fa0be2d60273d27b8e ffmpeg-$FFMPEG.tar.xz
|
||||
9985f141902a17de818e264d17c1ce334b748e499ee02fcb4703e4dc0038f89c v$MOLTENVK.tar.gz
|
||||
5a6226f7e23db51fdc3223121eba53f3f5447cf0cc4d6cb82a3a2df7a65d265d qtbase-everywhere-src-$QT.tar.xz
|
||||
498eabdf2381db96f808942b3e3c765f6360fe6c0e9961f0a45ff7a4c68d7a72 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
c02f355a58f3bbcf404a628bf488b6aeb2d84a94c269afdb86f6e529343ab01f qtsvg-everywhere-src-$QT.tar.xz
|
||||
8148408380ffea03101a26305c812b612ea30dbc07121e58707601522404d49b qttools-everywhere-src-$QT.tar.xz
|
||||
8e49a2df88a12c376a479ae7bd272a91cf57ebb4e7c0cf7341b3565df99d2314 qttranslations-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
8a89fb6612ace8954470aae004623374a8fc8b7a34a4277bee5527173b064faf shaderc-$SHADERC.tar.gz
|
||||
272d2725b140e09e85b96eecdc59c2e00c1a14cda2301767e1bf3c363a44b931 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
c693867f10a7760ef1bcf85419d51783586768cc2c601d03841bc6a8b2554b9c shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
06b0a042f2e121e954badb4fd78c9e2d4bc7ed6087eceb26ab559c23cf94334f shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
51dbf24fe72e43dd7cb9a289d3cab47112010f1a2ed69b6fc8ac0dff31991ed2 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
7bd4e79ce18b1d47517e7e91fbb7cf19d4f01942804a519bc7c0bf32b6325dd5 plutovg-$PLUTOVG.tar.gz
|
||||
78561b571ac224030cdc450ca2986b4de915c2ba7616004a6d71a379bffd15f3 plutosvg-$PLUTOSVG.tar.gz
|
||||
9d9938269adc25e9a9b84650338b87d130cf469d82685fffc028c325279619c1 rapidyaml-$RAPIDYAML-src.tgz
|
||||
|
||||
245002feccbe7f8361b223545a5654cea69780745886872d7efff50a38d96c66 shaderc-$SHADERC.tar.gz
|
||||
bd58dca4dac67dcf7640292d7d63e0416274d40ee2200f7301878cec11ac6647 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
1b220e3eec1714f0451b0e3652979bd280edf10893f617837b88e6359a804ded shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
cabb35f4eef0da3ef72ad9edd596af4191d7507a8f35c05df526d2d5ff889f59 shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
EOF
|
||||
|
||||
curl -L \
|
||||
-o "freetype-$FREETYPE.tar.xz" "https://sourceforge.net/projects/freetype/files/freetype2/$FREETYPE/freetype-$FREETYPE.tar.xz/download" \
|
||||
-o "harfbuzz-$HARFBUZZ.tar.gz" "https://github.com/harfbuzz/harfbuzz/archive/refs/tags/$HARFBUZZ.tar.gz" \
|
||||
-O "https://libsdl.org/release/$SDL.tar.gz" \
|
||||
-O "https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/releases/download/v$LZ4/lz4-$LZ4.tar.gz" \
|
||||
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
|
||||
-O "https://download.sourceforge.net/libpng-apng/libpng-$LIBPNG-apng.patch.gz" \
|
||||
-O "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/$LIBJPEGTURBO/libjpeg-turbo-$LIBJPEGTURBO.tar.gz" \
|
||||
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
|
||||
-O "https://ffmpeg.org/releases/ffmpeg-$FFMPEG.tar.xz" \
|
||||
-O "https://github.com/KhronosGroup/MoltenVK/archive/refs/tags/v$MOLTENVK.tar.gz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
|
||||
-o "QtApng-$QTAPNG.tar.gz" "https://github.com/jurplel/QtApng/archive/refs/tags/$QTAPNG.tar.gz" \
|
||||
-o "shaderc-$SHADERC.tar.gz" "https://github.com/google/shaderc/archive/refs/tags/v$SHADERC.tar.gz" \
|
||||
-o "shaderc-glslang-$SHADERC_GLSLANG.tar.gz" "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG.tar.gz" \
|
||||
-o "shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS.tar.gz" \
|
||||
-o "shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS.tar.gz" \
|
||||
-o "KDDockWidgets-$KDDOCKWIDGETS.tar.gz" "https://github.com/KDAB/KDDockWidgets/archive/v$KDDOCKWIDGETS.tar.gz" \
|
||||
-o "plutovg-$PLUTOVG.tar.gz" "https://github.com/sammycage/plutovg/archive/v$PLUTOVG.tar.gz" \
|
||||
-o "plutosvg-$PLUTOSVG.tar.gz" "https://github.com/sammycage/plutosvg/archive/v$PLUTOSVG.tar.gz"
|
||||
if ! shasum -sa 256 --check SHASUMS 2> /dev/null; then
|
||||
curl -L \
|
||||
-O "https://sourceforge.net/projects/freetype/files/freetype2/$FREETYPE/freetype-$FREETYPE.tar.xz" \
|
||||
-O "https://github.com/harfbuzz/harfbuzz/archive/$HARFBUZZ/harfbuzz-$HARFBUZZ.tar.gz" \
|
||||
-O "https://libsdl.org/release/$SDL.tar.gz" \
|
||||
-O "https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/releases/download/v$LZ4/lz4-$LZ4.tar.gz" \
|
||||
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
|
||||
-O "https://download.sourceforge.net/libpng-apng/libpng-$LIBPNG-apng.patch.gz" \
|
||||
-O "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/$LIBJPEGTURBO/libjpeg-turbo-$LIBJPEGTURBO.tar.gz" \
|
||||
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
|
||||
-O "https://ffmpeg.org/releases/ffmpeg-$FFMPEG.tar.xz" \
|
||||
-O "https://github.com/KhronosGroup/MoltenVK/archive/refs/tags/v$MOLTENVK.tar.gz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://github.com/jurplel/QtApng/archive/$QTAPNG/QtApng-$QTAPNG.tar.gz" \
|
||||
-O "https://github.com/google/shaderc/archive/v$SHADERC/shaderc-$SHADERC.tar.gz" \
|
||||
-O "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG/shaderc-glslang-$SHADERC_GLSLANG.tar.gz" \
|
||||
-O "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS/shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" \
|
||||
-O "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS/shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" \
|
||||
-O "https://github.com/KDAB/KDDockWidgets/archive/v$KDDOCKWIDGETS/KDDockWidgets-$KDDOCKWIDGETS.tar.gz" \
|
||||
-O "https://github.com/sammycage/plutovg/archive/v$PLUTOVG/plutovg-$PLUTOVG.tar.gz" \
|
||||
-O "https://github.com/sammycage/plutosvg/archive/v$PLUTOSVG/plutosvg-$PLUTOSVG.tar.gz" \
|
||||
-O "https://github.com/biojppm/rapidyaml/releases/download/v$RAPIDYAML/rapidyaml-$RAPIDYAML-src.tgz"
|
||||
fi
|
||||
|
||||
shasum -a 256 --check SHASUMS
|
||||
shasum -a 256 --check --strict SHASUMS
|
||||
|
||||
echo "Installing SDL..."
|
||||
rm -fr "$SDL"
|
||||
@@ -365,6 +373,15 @@ make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building RapidYAML..."
|
||||
rm -fr "rapidyaml-$RAPIDYAML-src"
|
||||
tar xf "rapidyaml-$RAPIDYAML-src.tgz"
|
||||
cd "rapidyaml-$RAPIDYAML-src"
|
||||
cmake "${CMAKE_COMMON[@]}" -DBUILD_SHARED_LIBS=ON -B build
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
echo "Cleaning up..."
|
||||
cd ..
|
||||
rm -rf deps-build
|
||||
|
||||
@@ -2,12 +2,24 @@
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
echo Setting environment...
|
||||
if exist "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsamd64_arm64.bat" (
|
||||
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsamd64_arm64.bat"
|
||||
) else if exist "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsamd64_arm64.bat" (
|
||||
call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsamd64_arm64.bat"
|
||||
rem Favour VS2022 over VS2026 for now.
|
||||
if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" (
|
||||
for /f "usebackq tokens=*" %%i in (`call "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -version "[17, 18)" -latest -property installationPath`) do set "VSINSTPATH=%%i"
|
||||
if defined VSINSTPATH (
|
||||
echo VSINSTPATH=!VSINSTPATH!
|
||||
call "!VSINSTPATH!\VC\Auxiliary\Build\vcvarsamd64_arm64.bat" || goto error
|
||||
) else (
|
||||
for /f "usebackq tokens=*" %%i in (`call "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -version "[18, 19)" -latest -property installationPath`) do set "VSINSTPATH=%%i"
|
||||
if defined VSINSTPATH (
|
||||
echo VSINSTPATH=!VSINSTPATH!
|
||||
call "!VSINSTPATH!\VC\Auxiliary\Build\vcvarsamd64_arm64.bat" || goto error
|
||||
) else (
|
||||
echo Visual Studio not found.
|
||||
goto error
|
||||
)
|
||||
)
|
||||
) else (
|
||||
echo Visual Studio 2022 not found.
|
||||
echo Visual Studio not found.
|
||||
goto error
|
||||
)
|
||||
|
||||
@@ -42,56 +54,60 @@ echo INSTALLDIR=%INSTALLDIR%
|
||||
|
||||
cd "%BUILDDIR%"
|
||||
|
||||
set FREETYPE=2.14.1
|
||||
set HARFBUZZ=12.2.0
|
||||
set LIBJPEGTURBO=3.1.2
|
||||
set LIBPNG=1653
|
||||
set LIBPNGLONG=1.6.53
|
||||
set SDL=SDL3-3.4.0
|
||||
set QT=6.10.1
|
||||
set QTMINOR=6.10
|
||||
set QT=6.11.0
|
||||
set QTMINOR=6.11
|
||||
set QTAPNG=1.3.0
|
||||
|
||||
set FREETYPE=2.14.1
|
||||
set HARFBUZZ=13.0.0
|
||||
set LIBJPEGTURBO=3.1.3
|
||||
set LIBPNG=1655
|
||||
set LIBPNGLONG=1.6.55
|
||||
set SDL=SDL3-3.4.2
|
||||
set LZ4=1.10.0
|
||||
set WEBP=1.6.0
|
||||
set ZLIB=1.3.1
|
||||
set ZLIBSHORT=131
|
||||
set ZLIB=1.3.2
|
||||
set ZLIBSHORT=132
|
||||
set ZSTD=1.5.7
|
||||
set KDDOCKWIDGETS=2.4.0
|
||||
set PLUTOVG=1.3.2
|
||||
set PLUTOSVG=0.0.7
|
||||
set RAPIDYAML=0.11.1
|
||||
|
||||
set SHADERC=2025.4
|
||||
set SHADERC_GLSLANG=7a47e2531cb334982b2a2dd8513dca0a3de4373d
|
||||
set SHADERC_SPIRVHEADERS=b824a462d4256d720bebb40e78b9eb8f78bbb305
|
||||
set SHADERC_SPIRVTOOLS=971a7b6e8d7740035bbff089bbbf9f42951ecfd5
|
||||
set SHADERC=2026.1
|
||||
set SHADERC_GLSLANG=f0bd0257c308b9a26562c1a30c4748a0219cc951
|
||||
set SHADERC_SPIRVHEADERS=04f10f650d514df88b76d25e83db360142c7b174
|
||||
set SHADERC_SPIRVTOOLS=fbe4f3ad913c44fe8700545f8ffe35d1382b7093
|
||||
|
||||
set AGILITYSDK=1.618.5
|
||||
|
||||
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 174d9e53402e1bf9ec7277e22ec199ba3e55a6be2c0740cb18c0ee9850fc8c34 || goto error
|
||||
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 31490c781bacd2ce56862555b11c51c964977c39f14f51b817dfaecf0be089fe || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1653.zip 140566abc64bb2320cb35f1d154d1cb3eb7174a12234d33bfdffb446bdc0a1d2 || goto error
|
||||
call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net/libpng-apng/libpng-%LIBPNGLONG%-apng.patch.gz 452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c || goto error
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 9ac2debb493e0d3e13dbd2729fb91f4bfeb00a0f4dff5e04b73cc9bac276b38d || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" c43f471a808b07fc541528410e94ce89c6745bdc1d744492e19911d35fbf7d33 || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 2d828d8c999fdd18167937c071781c22321c643b04a106c714411c2356cdb26d || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" ddd74a417d2397eb085d047a9b6ba52b76e748055817f728fe691f8456035d23 || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" db8e49ed50912c3c064a4f9ada7791c09eccec5a8d53463a19608eaab17679f0 || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 868eb651e395d48ade5932ef2c386e606e054eb5888ebe5284fbd8cb63ed935a || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 590d5ae246c85fa14d6458a36ff75a11236acfe8987c2475090aab1770acbdf8 || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 5dfb3c0cb84d2c935c1716b3b86358ca496fb9216676e7e28fee1357fb4a050e || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" c92e1b46170b8671bbd46c783939f0c2dba4986882c5ebd37aaa9eba5b224fbe || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" ded4420823cb7b1bc49f38c5c56dd43ec27b6577ccbc7f620790abfabcc33b62 || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" f9c4fd4fd73dff51e9043d2825b04361b678f63798ed798021ef47f1ff0bfccf || goto error
|
||||
call :downloadfile "QtApng-%QTAPNG%.zip" "https://github.com/jurplel/QtApng/archive/refs/tags/%QTAPNG%.zip" 5176082cdd468047a7eb1ec1f106b032f57df207aa318d559b29606b00d159ac || goto error
|
||||
|
||||
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 174d9e53402e1bf9ec7277e22ec199ba3e55a6be2c0740cb18c0ee9850fc8c34 || goto error
|
||||
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip a448a8abc3f9ae8eef19ef3ce247370957c1fada5d58a01b5e281e792f40fa61 || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1655.zip aa45ef52ff7a4e61f34af866b3254b0b243ddc42fe2adb823b0843d2a57c2e86 || goto error
|
||||
call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net/libpng-apng/libpng-%LIBPNGLONG%-apng.patch.gz 452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c || goto error
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 075920b826834ac4ddf97661cc73491047855859affd671d52079c6867c1c6c0 || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 4954d436c95c42aa258d4eb3fb95f8ecc5d7a3dc411f0f41ac2692d34b9b9e9c || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/refs/tags/v%LZ4%.zip" 3224b4c80f351f194984526ef396f6079bd6332dd9825c72ac0d7a37b3cdc565 || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://github.com/madler/zlib/releases/download/v%ZLIB%/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://github.com/madler/zlib/releases/download/v%ZLIB%/zlib%ZLIBSHORT%.zip" e8bf55f3017aa181690990cb58a994e77885da140609fc8f94abe9b65d2cae28 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error
|
||||
call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v%KDDOCKWIDGETS%.zip" 47ddb48197872055f0adf8e90a7235f8a3b795ca1ee3a28ac2c504c673ae3806 || goto error
|
||||
call :downloadfile "plutovg-%PLUTOVG%.zip" "https://github.com/sammycage/plutovg/archive/v%PLUTOVG%.zip" 4fe4e48f28aa80171b2166d45c0976ab0f21eecedb52cd4c3ef73b5afb48fac9 || goto error
|
||||
call :downloadfile "plutosvg-%PLUTOSVG%.zip" "https://github.com/sammycage/plutosvg/archive/v%PLUTOSVG%.zip" 82dee2c57ad712bdd6d6d81d3e76249d89caa4b5a4214353660fd5adff12201a || goto error
|
||||
call :downloadfile: "agility-sdk-%AGILITYSDK%.nupkg" "https://www.nuget.org/api/v2/package/Microsoft.Direct3D.D3D12/%AGILITYSDK%" 0027fc24f947c48dbded13ada7d280be221eb651644e23a8a476f0f1f0a079dd || goto error
|
||||
call :downloadfile "rapidyaml-%RAPIDYAML%-src.zip" "https://github.com/biojppm/rapidyaml/releases/download/v%RAPIDYAML%/rapidyaml-%RAPIDYAML%-src.zip" 30054b74abdf0ba35bf2cb435b6e49fcb6d62a8e78a240a018c36aa60dba765f || goto error
|
||||
|
||||
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" fab72d1a38eacea52710d18edb95dfd75db894ad869675d07a1eb26827da9b15 || goto error
|
||||
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 4a118247386ffba9160113f146f2189ba5abe3995db357114d7112ede6bd3cd1 || goto error
|
||||
call :downloadfile "shaderc-spirv-headers-%SHADERC_SPIRVHEADERS%.zip" "https://github.com/KhronosGroup/SPIRV-Headers/archive/%SHADERC_SPIRVHEADERS%.zip" 9a38cb3b14484f5038d78cd5df89404f2f5b389a6ad91f9f1df4ae71bb9490dc || goto error
|
||||
call :downloadfile "shaderc-spirv-tools-%SHADERC_SPIRVTOOLS%.zip" "https://github.com/KhronosGroup/SPIRV-Tools/archive/%SHADERC_SPIRVTOOLS%.zip" a26383c836a84fab5b03aed5d98e8e27d6c0a9cdbc3b0f462ccfe0a11a3d91ea || goto error
|
||||
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 3ac59c8216d367ab7858684d39c8faf872a64150aeb139335f4e083c5f79dde0 || goto error
|
||||
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 42a30acca4a35955370ed8ff6e54b823b4d4a5a86571baec1203d3fce87da447 || goto error
|
||||
call :downloadfile "shaderc-spirv-headers-%SHADERC_SPIRVHEADERS%.zip" "https://github.com/KhronosGroup/SPIRV-Headers/archive/%SHADERC_SPIRVHEADERS%.zip" 00ecd73dcaaa956cf2221ce899ce096e9535ba20695483c5277adede462d1bde || goto error
|
||||
call :downloadfile "shaderc-spirv-tools-%SHADERC_SPIRVTOOLS%.zip" "https://github.com/KhronosGroup/SPIRV-Tools/archive/%SHADERC_SPIRVTOOLS%.zip" 65b23ace0ff0c64daf51f7741ebb6448899fa4aceefc72403e56f5b95607ca8e || goto error
|
||||
|
||||
if %DEBUG%==1 (
|
||||
echo Building debug and release libraries...
|
||||
@@ -207,7 +223,7 @@ echo Building Qt base...
|
||||
rmdir /S /Q "qtbase-everywhere-src-%QT%"
|
||||
%SEVENZIP% x "qtbase-everywhere-src-%QT%.zip" || goto error
|
||||
cd "qtbase-everywhere-src-%QT%" || goto error
|
||||
cmake -B build %ARM64TOOLCHAIN% -DFEATURE_sql=OFF -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DQT_HOST_PATH="%X64INSTALLDIR%" %FORCEPDB% -DINPUT_gui=yes -DINPUT_widgets=yes -DINPUT_ssl=yes -DINPUT_openssl=no -DINPUT_schannel=yes -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON %QTBUILDSPEC% || goto error
|
||||
cmake -B build %ARM64TOOLCHAIN% -DFEATURE_sql=OFF -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DQT_HOST_PATH="%X64INSTALLDIR%" %FORCEPDB% -DINPUT_gui=yes -DINPUT_widgets=yes -DINPUT_ssl=yes -DINPUT_openssl=no -DINPUT_schannel=yes -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON -DQT_FEATURE_windows_ioring=OFF %QTBUILDSPEC% || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
@@ -308,6 +324,15 @@ cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
echo "Building RapidYAML..."
|
||||
rmdir /S /Q "rapidyaml-%RAPIDYAML%-src"
|
||||
%SEVENZIP% x "rapidyaml-%RAPIDYAML%-src.zip" || goto error
|
||||
cd "rapidyaml-%RAPIDYAML%-src" || goto error
|
||||
cmake %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -B build -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
echo Unpacking Agility SDK
|
||||
rmdir /S /Q "agility-sdk-%AGILITYSDK%"
|
||||
%SEVENZIP% x -o"agility-sdk-%AGILITYSDK%" "agility-sdk-%AGILITYSDK%.nupkg" || goto error
|
||||
|
||||
@@ -2,17 +2,32 @@
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
echo Setting environment...
|
||||
if exist "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" (
|
||||
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
) else if exist "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" (
|
||||
call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
|
||||
rem Favour VS2022 over VS2026 for now.
|
||||
if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" (
|
||||
for /f "usebackq tokens=*" %%i in (`call "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -version "[17, 18)" -latest -property installationPath`) do set "VSINSTPATH=%%i"
|
||||
if defined VSINSTPATH (
|
||||
echo VSINSTPATH=!VSINSTPATH!
|
||||
call "!VSINSTPATH!\VC\Auxiliary\Build\vcvars64.bat" || goto error
|
||||
) else (
|
||||
for /f "usebackq tokens=*" %%i in (`call "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -version "[18, 19)" -latest -property installationPath`) do set "VSINSTPATH=%%i"
|
||||
if defined VSINSTPATH (
|
||||
echo VSINSTPATH=!VSINSTPATH!
|
||||
call "!VSINSTPATH!\VC\Auxiliary\Build\vcvars64.bat" || goto error
|
||||
) else (
|
||||
echo Visual Studio not found.
|
||||
goto error
|
||||
)
|
||||
)
|
||||
) else (
|
||||
echo Visual Studio 2022 not found.
|
||||
echo Visual Studio not found.
|
||||
goto error
|
||||
)
|
||||
|
||||
set SEVENZIP="C:\Program Files\7-Zip\7z.exe"
|
||||
set PATCH="C:\Program Files\Git\usr\bin\patch.exe"
|
||||
set BASH="C:\Program Files\Git\usr\bin\bash.exe"
|
||||
|
||||
set "UNIX_TOOLS=C:\Program Files\Git\usr\bin\"
|
||||
|
||||
if defined DEBUG (
|
||||
echo DEBUG=%DEBUG%
|
||||
@@ -20,6 +35,12 @@ if defined DEBUG (
|
||||
set DEBUG=1
|
||||
)
|
||||
|
||||
if defined BUILD_FFMPEG (
|
||||
echo BUILD_FFMPEG=%BUILD_FFMPEG%
|
||||
) else (
|
||||
set BUILD_FFMPEG=0
|
||||
)
|
||||
|
||||
pushd %~dp0
|
||||
set "SCRIPTDIR=%CD%"
|
||||
cd ..\..\..\..
|
||||
@@ -40,56 +61,80 @@ set "PATH=%PATH%;%INSTALLDIR%\bin"
|
||||
|
||||
cd "%BUILDDIR%"
|
||||
|
||||
set FREETYPE=2.14.1
|
||||
set HARFBUZZ=12.2.0
|
||||
set LIBJPEGTURBO=3.1.2
|
||||
set LIBPNG=1653
|
||||
set LIBPNGLONG=1.6.53
|
||||
set SDL=SDL3-3.4.0
|
||||
set QT=6.10.1
|
||||
set QTMINOR=6.10
|
||||
set QT=6.11.0
|
||||
set QTMINOR=6.11
|
||||
set QTAPNG=1.3.0
|
||||
|
||||
set FFMPEG=8.1
|
||||
set MESON=1.10.2
|
||||
set PKGCONF=2.5.1
|
||||
set AMF=1.5.0
|
||||
set LIBVPL=2.16.0
|
||||
set NVENC=13.0.19.0
|
||||
set LIBOPUS=1.6.1
|
||||
set LIBSVTAV1=4.0.1
|
||||
set LIBX264=b35605ace3ddf7c1a5d67a2eb553f034aef41d55
|
||||
|
||||
set FREETYPE=2.14.1
|
||||
set HARFBUZZ=13.0.0
|
||||
set LIBJPEGTURBO=3.1.3
|
||||
set LIBPNG=1655
|
||||
set LIBPNGLONG=1.6.55
|
||||
set SDL=SDL3-3.4.2
|
||||
set LZ4=1.10.0
|
||||
set WEBP=1.6.0
|
||||
set ZLIB=1.3.1
|
||||
set ZLIBSHORT=131
|
||||
set ZLIB=1.3.2
|
||||
set ZLIBSHORT=132
|
||||
set ZSTD=1.5.7
|
||||
set KDDOCKWIDGETS=2.4.0
|
||||
set PLUTOVG=1.3.2
|
||||
set PLUTOSVG=0.0.7
|
||||
set RAPIDYAML=0.11.1
|
||||
|
||||
set SHADERC=2025.4
|
||||
set SHADERC_GLSLANG=7a47e2531cb334982b2a2dd8513dca0a3de4373d
|
||||
set SHADERC_SPIRVHEADERS=b824a462d4256d720bebb40e78b9eb8f78bbb305
|
||||
set SHADERC_SPIRVTOOLS=971a7b6e8d7740035bbff089bbbf9f42951ecfd5
|
||||
set SHADERC=2026.1
|
||||
set SHADERC_GLSLANG=f0bd0257c308b9a26562c1a30c4748a0219cc951
|
||||
set SHADERC_SPIRVHEADERS=04f10f650d514df88b76d25e83db360142c7b174
|
||||
set SHADERC_SPIRVTOOLS=fbe4f3ad913c44fe8700545f8ffe35d1382b7093
|
||||
|
||||
set AGILITYSDK=1.618.5
|
||||
set AGILITYSDK=1.619.0
|
||||
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 590d5ae246c85fa14d6458a36ff75a11236acfe8987c2475090aab1770acbdf8 || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 5dfb3c0cb84d2c935c1716b3b86358ca496fb9216676e7e28fee1357fb4a050e || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" c92e1b46170b8671bbd46c783939f0c2dba4986882c5ebd37aaa9eba5b224fbe || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" ded4420823cb7b1bc49f38c5c56dd43ec27b6577ccbc7f620790abfabcc33b62 || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" f9c4fd4fd73dff51e9043d2825b04361b678f63798ed798021ef47f1ff0bfccf || goto error
|
||||
call :downloadfile "QtApng-%QTAPNG%.zip" "https://github.com/jurplel/QtApng/archive/refs/tags/%QTAPNG%.zip" 5176082cdd468047a7eb1ec1f106b032f57df207aa318d559b29606b00d159ac || goto error
|
||||
|
||||
call :downloadfile "ffmpeg-%FFMPEG%.tar.xz" "https://ffmpeg.org/releases/ffmpeg-%FFMPEG%.tar.xz" b072aed6871998cce9b36e7774033105ca29e33632be5b6347f3206898e0756a || goto error
|
||||
call :downloadfile "meson-%MESON%.tar.gz" "https://github.com/mesonbuild/meson/releases/download/%MESON%/meson-%MESON%.tar.gz" 7890287d911dd4ee1ebd0efb61ed0321bfcd87c725df923a837cf90c6508f96b || goto error
|
||||
call :downloadfile "pkgconf-pkgconf-%PKGCONF%.zip" "https://github.com/pkgconf/pkgconf/archive/refs/tags/pkgconf-%PKGCONF%.zip" c5b5f88a2ca2324dc5d857e35bb145e24290e326357ea94a86d47b8d7fa15477 || goto error
|
||||
call :downloadfile "amf-headers-v%AMF%.tar.gz" "https://github.com/GPUOpen-LibrariesAndSDKs/AMF/releases/download/v%AMF%/AMF-headers-v%AMF%.tar.gz" d569647fa26f289affe81a206259fa92f819d06db1e80cc334559953e82a3f01 || goto error
|
||||
call :downloadfile "libvpl-%LIBVPL%.zip" "https://github.com/intel/libvpl/archive/v%LIBVPL%.zip" 0b2ee8da8b9ef07ed4b52bf9ddee05008ec999b7c3c41944d7a9f804631c398e || goto error
|
||||
call :downloadfile "nv-codec-headers-%NVENC%.tar.gz" "https://github.com/FFmpeg/nv-codec-headers/releases/download/n%NVENC%/nv-codec-headers-%NVENC%.tar.gz" 13da39edb3a40ed9713ae390ca89faa2f1202c9dda869ef306a8d4383e242bee || goto error
|
||||
call :downloadfile "opus-%LIBOPUS%.tar.gz" "https://downloads.xiph.org/releases/opus/opus-%LIBOPUS%.tar.gz" 6ffcb593207be92584df15b32466ed64bbec99109f007c82205f0194572411a1 || goto error
|
||||
call :downloadfile "SVT-AV1-v%LIBSVTAV1%.zip" "https://gitlab.com/AOMediaCodec/SVT-AV1/-/archive/v%LIBSVTAV1%/SVT-AV1-v%LIBSVTAV1%.zip" bfafad9af17f87fff75e44ca9b2c10cdd83c576047c3e96229285a8a64c81afc || goto error
|
||||
call :downloadfile "x264-%LIBX264%.zip" "https://code.videolan.org/videolan/x264/-/archive/%LIBX264%.zip" d95d059eff81cc565165cd058b66e208f0cc9874106a8fe94a811a66cf8a85a2 || goto error
|
||||
|
||||
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 174d9e53402e1bf9ec7277e22ec199ba3e55a6be2c0740cb18c0ee9850fc8c34 || goto error
|
||||
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 31490c781bacd2ce56862555b11c51c964977c39f14f51b817dfaecf0be089fe || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1653.zip 140566abc64bb2320cb35f1d154d1cb3eb7174a12234d33bfdffb446bdc0a1d2 || goto error
|
||||
call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net/libpng-apng/libpng-%LIBPNGLONG%-apng.patch.gz 452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c || goto error
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf || goto error
|
||||
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip a448a8abc3f9ae8eef19ef3ce247370957c1fada5d58a01b5e281e792f40fa61 || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1655.zip aa45ef52ff7a4e61f34af866b3254b0b243ddc42fe2adb823b0843d2a57c2e86 || goto error
|
||||
call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net/libpng-apng/libpng-%LIBPNGLONG%-apng.patch.gz 017c06f75ffed25f6cda9b5369ec6da0ac35a6616adf7abe4222516a0237f37a || goto error
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 075920b826834ac4ddf97661cc73491047855859affd671d52079c6867c1c6c0 || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 9ac2debb493e0d3e13dbd2729fb91f4bfeb00a0f4dff5e04b73cc9bac276b38d || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" c43f471a808b07fc541528410e94ce89c6745bdc1d744492e19911d35fbf7d33 || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 2d828d8c999fdd18167937c071781c22321c643b04a106c714411c2356cdb26d || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" ddd74a417d2397eb085d047a9b6ba52b76e748055817f728fe691f8456035d23 || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" db8e49ed50912c3c064a4f9ada7791c09eccec5a8d53463a19608eaab17679f0 || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 868eb651e395d48ade5932ef2c386e606e054eb5888ebe5284fbd8cb63ed935a || goto error
|
||||
call :downloadfile "QtApng-%QTAPNG%.zip" "https://github.com/jurplel/QtApng/archive/refs/tags/%QTAPNG%.zip" 5176082cdd468047a7eb1ec1f106b032f57df207aa318d559b29606b00d159ac || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 4954d436c95c42aa258d4eb3fb95f8ecc5d7a3dc411f0f41ac2692d34b9b9e9c || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/refs/tags/v%LZ4%.zip" 3224b4c80f351f194984526ef396f6079bd6332dd9825c72ac0d7a37b3cdc565 || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://github.com/madler/zlib/releases/download/v%ZLIB%/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://github.com/madler/zlib/releases/download/v%ZLIB%/zlib%ZLIBSHORT%.zip" e8bf55f3017aa181690990cb58a994e77885da140609fc8f94abe9b65d2cae28 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error
|
||||
call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v%KDDOCKWIDGETS%.zip" 47ddb48197872055f0adf8e90a7235f8a3b795ca1ee3a28ac2c504c673ae3806 || goto error
|
||||
call :downloadfile "plutovg-%PLUTOVG%.zip" "https://github.com/sammycage/plutovg/archive/v%PLUTOVG%.zip" 4fe4e48f28aa80171b2166d45c0976ab0f21eecedb52cd4c3ef73b5afb48fac9 || goto error
|
||||
call :downloadfile "plutosvg-%PLUTOSVG%.zip" "https://github.com/sammycage/plutosvg/archive/v%PLUTOSVG%.zip" 82dee2c57ad712bdd6d6d81d3e76249d89caa4b5a4214353660fd5adff12201a || goto error
|
||||
call :downloadfile: "agility-sdk-%AGILITYSDK%.nupkg" "https://www.nuget.org/api/v2/package/Microsoft.Direct3D.D3D12/%AGILITYSDK%" 0027fc24f947c48dbded13ada7d280be221eb651644e23a8a476f0f1f0a079dd || goto error
|
||||
call :downloadfile "agility-sdk-%AGILITYSDK%.nupkg" "https://www.nuget.org/api/v2/package/Microsoft.Direct3D.D3D12/%AGILITYSDK%" d5edab9a0c4d1b78ba6fe55b425eeef9fefba7d2a101e889d70fd21d481e6cb1 || goto error
|
||||
call :downloadfile "rapidyaml-%RAPIDYAML%-src.zip" "https://github.com/biojppm/rapidyaml/releases/download/v%RAPIDYAML%/rapidyaml-%RAPIDYAML%-src.zip" 30054b74abdf0ba35bf2cb435b6e49fcb6d62a8e78a240a018c36aa60dba765f || goto error
|
||||
|
||||
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" fab72d1a38eacea52710d18edb95dfd75db894ad869675d07a1eb26827da9b15 || goto error
|
||||
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 4a118247386ffba9160113f146f2189ba5abe3995db357114d7112ede6bd3cd1 || goto error
|
||||
call :downloadfile "shaderc-spirv-headers-%SHADERC_SPIRVHEADERS%.zip" "https://github.com/KhronosGroup/SPIRV-Headers/archive/%SHADERC_SPIRVHEADERS%.zip" 9a38cb3b14484f5038d78cd5df89404f2f5b389a6ad91f9f1df4ae71bb9490dc || goto error
|
||||
call :downloadfile "shaderc-spirv-tools-%SHADERC_SPIRVTOOLS%.zip" "https://github.com/KhronosGroup/SPIRV-Tools/archive/%SHADERC_SPIRVTOOLS%.zip" a26383c836a84fab5b03aed5d98e8e27d6c0a9cdbc3b0f462ccfe0a11a3d91ea || goto error
|
||||
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 3ac59c8216d367ab7858684d39c8faf872a64150aeb139335f4e083c5f79dde0 || goto error
|
||||
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 42a30acca4a35955370ed8ff6e54b823b4d4a5a86571baec1203d3fce87da447 || goto error
|
||||
call :downloadfile "shaderc-spirv-headers-%SHADERC_SPIRVHEADERS%.zip" "https://github.com/KhronosGroup/SPIRV-Headers/archive/%SHADERC_SPIRVHEADERS%.zip" 00ecd73dcaaa956cf2221ce899ce096e9535ba20695483c5277adede462d1bde || goto error
|
||||
call :downloadfile "shaderc-spirv-tools-%SHADERC_SPIRVTOOLS%.zip" "https://github.com/KhronosGroup/SPIRV-Tools/archive/%SHADERC_SPIRVTOOLS%.zip" 65b23ace0ff0c64daf51f7741ebb6448899fa4aceefc72403e56f5b95607ca8e || goto error
|
||||
|
||||
if %DEBUG%==1 (
|
||||
echo Building debug and release libraries...
|
||||
@@ -99,6 +144,139 @@ if %DEBUG%==1 (
|
||||
|
||||
set FORCEPDB=-DCMAKE_SHARED_LINKER_FLAGS_RELEASE="/DEBUG" -DCMAKE_MODULE_LINKER_FLAGS_RELEASE="/DEBUG" -DCMAKE_SHARED_LINKER_FLAGS_MINSIZEREL="/DEBUG" -DCMAKE_MODULE_LINKER_FLAGS_MINSIZEREL="/DEBUG"
|
||||
|
||||
if %BUILD_FFMPEG%==1 (
|
||||
if not "%INSTALLDIR%"=="%INSTALLDIR: =%" (
|
||||
echo FFmpeg does not support building in paths with spaces.
|
||||
goto error
|
||||
)
|
||||
|
||||
where nasm /q
|
||||
set FOUND_NASM=0
|
||||
if !ERRORLEVEL!==0 (
|
||||
set FOUND_NASM=1
|
||||
)
|
||||
|
||||
echo "Installing AMF headers"
|
||||
rmdir /S /Q "amf-headers-v%AMF%"
|
||||
tar -xf "amf-headers-v%AMF%.tar.gz" || goto error
|
||||
xcopy "%BUILDDIR%\amf-headers-v%AMF%\AMF" "%INSTALLDIR%\include\AMF\" /y /s || goto error
|
||||
echo.
|
||||
|
||||
echo "Installing libvpl"
|
||||
rmdir /S /Q "libvpl-%LIBVPL%"
|
||||
%SEVENZIP% x "libvpl-%LIBVPL%.zip" || goto error
|
||||
cd "libvpl-%LIBVPL%" || goto error
|
||||
cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=OFF -DINSTALL_EXAMPLES=OFF -DINSTALL_LIB=OFF -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -B build -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
echo "Installing libopus"
|
||||
rmdir /S /Q "opus-%LIBOPUS%"
|
||||
tar -xf "opus-%LIBOPUS%.tar.gz" || goto error
|
||||
cd "opus-%LIBOPUS%" || goto error
|
||||
cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=OFF -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -B build -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
echo "Installing libsvtav1"
|
||||
rmdir /S /Q "SVT-AV1-v%LIBSVTAV1%"
|
||||
tar -xf "SVT-AV1-v%LIBSVTAV1%.zip" || goto error
|
||||
cd "SVT-AV1-v%LIBSVTAV1%" || goto error
|
||||
if !FOUND_NASM!==0 (
|
||||
set LIBSTVAV1_NASM=-DCOMPILE_C_ONLY=ON
|
||||
)
|
||||
cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTING=OFF -DBUILD_APPS=OFF -DSVT_AV1_LTO=ON !LIBSTVAV1_NASM! -B build -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
echo "Extracting meson"
|
||||
rmdir /S /Q "meson-%MESON%"
|
||||
tar xf "meson-%MESON%.tar.gz" || goto error
|
||||
set MASON_PY=python "%BUILDDIR%\meson-%MESON%\meson.py"
|
||||
!MASON_PY! -v || goto error
|
||||
echo.
|
||||
|
||||
rem Alternatively we could grab pkg-config-lite from chocolatey or WinGet.
|
||||
echo "Installing pkgconf"
|
||||
rmdir /S /Q "pkgconf-pkgconf-%PKGCONF%"
|
||||
%SEVENZIP% x "pkgconf-pkgconf-%PKGCONF%.zip" || goto error
|
||||
cd "pkgconf-pkgconf-%PKGCONF%" || goto error
|
||||
!MASON_PY! setup --buildtype=release --prefix="%INSTALLDIR%" -Dtests=disabled build --backend=ninja || goto error
|
||||
!MASON_PY! compile -C build || goto error
|
||||
ninja -C build install || goto error
|
||||
set PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1
|
||||
set PKG_CONFIG_ALLOW_SYSTEM_LIBS=1
|
||||
Set "PKG_CONFIG_PATH=%INSTALLDIR%\lib\pkgconfig"
|
||||
cd .. || goto error
|
||||
|
||||
set "OLD_PATH=%PATH%"
|
||||
set "PATH=%PATH%;%UNIX_TOOLS%"
|
||||
|
||||
echo "Installing nvenc headers..."
|
||||
rmdir /S /Q "nv-codec-headers-%NVENC%"
|
||||
tar xf "nv-codec-headers-%NVENC%.tar.gz" || goto error
|
||||
make -C "nv-codec-headers-%NVENC%" PREFIX="%INSTALLDIR%" install || goto error
|
||||
echo.
|
||||
|
||||
set CC=cl
|
||||
set CXX=cl
|
||||
|
||||
echo "Installing libx264"
|
||||
rmdir /S /Q "x264-%LIBX264%"
|
||||
%SEVENZIP% x "x264-%LIBX264%.zip" || goto error
|
||||
cd "x264-%LIBX264%" || goto error
|
||||
if !FOUND_NASM!==0 (
|
||||
set LIBX264_NASM=--disable-asm
|
||||
)
|
||||
%BASH% configure --prefix="%INSTALLDIR%" --disable-cli --enable-static --extra-cflags="-MD -w -Os -GL" !LIBX264_NASM! || goto error
|
||||
make -j%NUMBER_OF_PROCESSORS% || goto error
|
||||
make install || goto error
|
||||
cd .. || goto error
|
||||
echo.
|
||||
|
||||
echo "Installing FFmpeg..."
|
||||
rmdir /S /Q "ffmpeg-%FFMPEG%"
|
||||
tar xf "ffmpeg-%FFMPEG%.tar.xz" || goto error
|
||||
cd "ffmpeg-%FFMPEG%"
|
||||
%PATCH% -p1 < "%SCRIPTDIR%\ffmpeg-configure-escape.patch" || goto error
|
||||
if not !FOUND_NASM!==1 (
|
||||
rem MSVC LTO gives linker errors when building without nasm.
|
||||
rem The following patches fixes that issue.
|
||||
%PATCH% -p1 < "%SCRIPTDIR%\ffmpeg-no-nasm-fix-avc-air.patch" || goto error
|
||||
%PATCH% -p1 < "%SCRIPTDIR%\ffmpeg-no-nasm-fix-swc-air.patch" || goto error
|
||||
set FFMPEG_NASM=--disable-x86asm
|
||||
)
|
||||
rem FFmpeg's build seems to choke when extra-cflags contain `\`, so use `/` as the path separator.
|
||||
set VULKAN_INCLUDE=%INSTALLDIR:\=/%/../3rdparty/vulkan/include
|
||||
rem libvpl needs to have advapi32.lib & ole32.lib added as extra libs.
|
||||
rem For some reason QSV requires the hevc parser on windows.
|
||||
rem --enable-small removes the display names of codecs, so instead we specify optflag for minsize
|
||||
%BASH% configure --prefix="%INSTALLDIR%" --disable-all --disable-autodetect --disable-static --enable-shared --disable-debug ^
|
||||
--toolchain=msvc --extra-ldflags="-LTCG" --extra-libs="advapi32.lib ole32.lib" !FFMPEG_NASM! --pkg-config="%INSTALLDIR%\bin\pkgconf.exe" ^
|
||||
--extra-cflags="-MD -GL -I!VULKAN_INCLUDE!" --extra-cxxflags="-MD -GL -I!VULKAN_INCLUDE!" --optflags="-O1" ^
|
||||
--enable-avcodec --enable-avformat --enable-avutil --enable-swresample --enable-swscale ^
|
||||
--enable-gpl --enable-libx264 --enable-libsvtav1 --enable-libopus --enable-vulkan --enable-ffnvcodec --enable-nvenc --enable-libvpl --enable-amf ^
|
||||
--enable-d3d11va --enable-mediafoundation ^
|
||||
--enable-encoder=ffv1,qtrle,libx264*,libsvtav1,aac,flac,libopus,pcm_s16be,pcm_s16le ^
|
||||
--enable-encoder=h264_qsv,hevc_qsv,av1_qsv ^
|
||||
--enable-encoder=h264_nvenc,hevc_nvenc,av1_nvenc ^
|
||||
--enable-encoder=h264_amf,hevc_amf,av1_amf ^
|
||||
--enable-encoder=h264_vulkan,hevc_vulkan,av1_vulkan ^
|
||||
--enable-encoder=h264_mf,hevc_mf,av1_mf ^
|
||||
--enable-parser=hevc ^
|
||||
--enable-muxer=avi,matroska,mov,mp3,mp4,wav ^
|
||||
--enable-protocol=file || goto error
|
||||
make -j%NUMBER_OF_PROCESSORS% || goto error
|
||||
make install || goto error
|
||||
cd ..
|
||||
echo.
|
||||
|
||||
set "PATH=!OLD_PATH!"
|
||||
)
|
||||
|
||||
echo Building Zlib...
|
||||
rmdir /S /Q "zlib-%ZLIB%"
|
||||
%SEVENZIP% x "zlib%ZLIBSHORT%.zip" || goto error
|
||||
@@ -188,7 +366,7 @@ echo Building SDL...
|
||||
rmdir /S /Q "%SDL%"
|
||||
%SEVENZIP% x "%SDL%.zip" || goto error
|
||||
cd "%SDL%" || goto error
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release %FORCEPDB% -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DSDL_SHARED=ON -DSDL_STATIC=OFF -G Ninja || goto error
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release %FORCEPDB% -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DSDL_SHARED=ON -DSDL_STATIC=OFF -DSDL_TESTS=OFF -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
copy build\SDL3.pdb "%INSTALLDIR%\bin" || goto error
|
||||
@@ -204,7 +382,7 @@ echo Building Qt base...
|
||||
rmdir /S /Q "qtbase-everywhere-src-%QT%"
|
||||
%SEVENZIP% x "qtbase-everywhere-src-%QT%.zip" || goto error
|
||||
cd "qtbase-everywhere-src-%QT%" || goto error
|
||||
cmake -B build -DFEATURE_sql=OFF -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" %FORCEPDB% -DINPUT_gui=yes -DINPUT_widgets=yes -DINPUT_ssl=yes -DINPUT_openssl=no -DINPUT_schannel=yes -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON %QTBUILDSPEC% || goto error
|
||||
cmake -B build -DFEATURE_sql=OFF -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" %FORCEPDB% -DINPUT_gui=yes -DINPUT_widgets=yes -DINPUT_ssl=yes -DINPUT_openssl=no -DINPUT_schannel=yes -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON -DQT_FEATURE_windows_ioring=OFF %QTBUILDSPEC% || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
@@ -305,6 +483,15 @@ cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
echo "Building RapidYAML..."
|
||||
rmdir /S /Q "rapidyaml-%RAPIDYAML%-src"
|
||||
%SEVENZIP% x "rapidyaml-%RAPIDYAML%-src.zip" || goto error
|
||||
cd "rapidyaml-%RAPIDYAML%-src" || goto error
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -B build -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
echo Unpacking Agility SDK
|
||||
rmdir /S /Q "agility-sdk-%AGILITYSDK%"
|
||||
%SEVENZIP% x -o"agility-sdk-%AGILITYSDK%" "agility-sdk-%AGILITYSDK%.nupkg" || goto error
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/configure b/configure
|
||||
index 747cbe6f40..c8a029cf19 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -5190,7 +5190,7 @@ probe_cc(){
|
||||
_DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< 2>&1 | awk '\''/including/ { sub(/^.*file: */, ""); if (!match($$0, / /)) { print $$0 } }'\'' | xargs -r -d\\n -n1 wslpath -u | awk '\''BEGIN { printf "%s:", "$@" }; { sub(/\r/,""); printf " %s", $$0 }; END { print "" }'\'' > $(@:.o=.d)'
|
||||
|
||||
else
|
||||
- _DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< 2>&1 | awk '\''/including/ { sub(/^.*file: */, ""); gsub(/\\/, "/"); if (!match($$0, / /)) print "$@:", $$0 }'\'' > $(@:.o=.d)'
|
||||
+ _DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< 2>&1 | awk '\''/including/ { sub(/^.*file: */, ""); gsub(/\\\\/, "/"); if (!match($$0, / /)) print "$@:", $$0 }'\'' > $(@:.o=.d)'
|
||||
fi
|
||||
_DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -showIncludes -Zs'
|
||||
_cflags_speed="-O2"
|
||||
@@ -0,0 +1,29 @@
|
||||
diff --git a/libavcodec/x86/lpc_init.c b/libavcodec/x86/lpc_init.c
|
||||
index f2fca53799..da2c5a526d 100644
|
||||
--- a/libavcodec/x86/lpc_init.c
|
||||
+++ b/libavcodec/x86/lpc_init.c
|
||||
@@ -19,6 +19,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
+#include "config.h"
|
||||
#include "libavutil/attributes.h"
|
||||
#include "libavutil/x86/asm.h"
|
||||
#include "libavutil/x86/cpu.h"
|
||||
@@ -112,9 +113,13 @@ av_cold void ff_lpc_init_x86(LPCContext *c)
|
||||
c->lpc_compute_autocorr = lpc_compute_autocorr_sse2;
|
||||
#endif
|
||||
|
||||
+#if HAVE_SSE2_EXTERNAL
|
||||
if (EXTERNAL_SSE2(cpu_flags))
|
||||
c->lpc_apply_welch_window = ff_lpc_apply_welch_window_sse2;
|
||||
+#endif
|
||||
|
||||
+#if HAVE_AVX2_EXTERNAL
|
||||
if (EXTERNAL_AVX2(cpu_flags))
|
||||
c->lpc_apply_welch_window = ff_lpc_apply_welch_window_avx2;
|
||||
+#endif
|
||||
}
|
||||
--
|
||||
2.43.0.windows.1
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
diff --git a/libswscale/x86/rgb2rgb.c b/libswscale/x86/rgb2rgb.c
|
||||
index 48a73bd0b2..718b90ec81 100644
|
||||
--- a/libswscale/x86/rgb2rgb.c
|
||||
+++ b/libswscale/x86/rgb2rgb.c
|
||||
@@ -2439,6 +2439,7 @@ av_cold void rgb2rgb_init_x86(void)
|
||||
deinterleaveBytes = deinterleave_bytes_sse2;
|
||||
}
|
||||
#endif
|
||||
+#if HAVE_SSE3_EXTERNAL
|
||||
if (EXTERNAL_SSSE3(cpu_flags)) {
|
||||
shuffle_bytes_0321 = ff_shuffle_bytes_0321_ssse3;
|
||||
shuffle_bytes_2103 = ff_shuffle_bytes_2103_ssse3;
|
||||
@@ -2450,6 +2451,7 @@ av_cold void rgb2rgb_init_x86(void)
|
||||
shuffle_bytes_2130 = ff_shuffle_bytes_2130_ssse3;
|
||||
shuffle_bytes_1203 = ff_shuffle_bytes_1203_ssse3;
|
||||
}
|
||||
+#endif
|
||||
#if HAVE_AVX_EXTERNAL
|
||||
if (EXTERNAL_AVX(cpu_flags)) {
|
||||
deinterleaveBytes = deinterleave_bytes_avx;
|
||||
diff --git a/libswscale/x86/swscale.c b/libswscale/x86/swscale.c
|
||||
index 8b6f9bd58a..33b9673779 100644
|
||||
--- a/libswscale/x86/swscale.c
|
||||
+++ b/libswscale/x86/swscale.c
|
||||
@@ -473,6 +473,7 @@ RANGE_CONVERT_FUNCS_DECL(avx2, 16)
|
||||
|
||||
av_cold void ff_sws_init_range_convert_x86(SwsInternal *c)
|
||||
{
|
||||
+#if HAVE_X86ASM
|
||||
int cpu_flags = av_get_cpu_flags();
|
||||
if (EXTERNAL_AVX2_FAST(cpu_flags)) {
|
||||
if (c->dstBpc <= 14) {
|
||||
@@ -485,6 +486,7 @@ av_cold void ff_sws_init_range_convert_x86(SwsInternal *c)
|
||||
} else if (EXTERNAL_SSE4(cpu_flags) && c->dstBpc > 14) {
|
||||
RANGE_CONVERT_FUNCS(sse4, 16);
|
||||
}
|
||||
+#endif
|
||||
}
|
||||
|
||||
av_cold void ff_sws_init_swscale_x86(SwsInternal *c)
|
||||
@@ -569,6 +571,7 @@ switch(c->dstBpc){ \
|
||||
else ASSIGN_SCALE_FUNC2(hscalefn, X8, opt1, opt2); \
|
||||
break; \
|
||||
}
|
||||
+#if HAVE_SSE2_EXTERNAL
|
||||
if (EXTERNAL_SSE2(cpu_flags)) {
|
||||
ASSIGN_SSE_SCALE_FUNC(c->hyScale, c->hLumFilterSize, sse2, sse2);
|
||||
ASSIGN_SSE_SCALE_FUNC(c->hcScale, c->hChrFilterSize, sse2, sse2);
|
||||
@@ -607,6 +610,8 @@ switch(c->dstBpc){ \
|
||||
break;
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
+#if HAVE_SSE3_EXTERNAL
|
||||
if (EXTERNAL_SSSE3(cpu_flags)) {
|
||||
ASSIGN_SSE_SCALE_FUNC(c->hyScale, c->hLumFilterSize, ssse3, ssse3);
|
||||
ASSIGN_SSE_SCALE_FUNC(c->hcScale, c->hChrFilterSize, ssse3, ssse3);
|
||||
@@ -617,6 +622,8 @@ switch(c->dstBpc){ \
|
||||
break;
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
+#if HAVE_SSE4_EXTERNAL
|
||||
if (EXTERNAL_SSE4(cpu_flags)) {
|
||||
/* Xto15 don't need special sse4 functions */
|
||||
ASSIGN_SSE_SCALE_FUNC(c->hyScale, c->hLumFilterSize, sse4, ssse3);
|
||||
@@ -627,7 +634,9 @@ switch(c->dstBpc){ \
|
||||
if (c->dstBpc == 16 && !isBE(c->opts.dst_format) && !(c->opts.flags & SWS_ACCURATE_RND))
|
||||
c->yuv2plane1 = ff_yuv2plane1_16_sse4;
|
||||
}
|
||||
+#endif
|
||||
|
||||
+#if HAVE_AVX_EXTERNAL
|
||||
if (EXTERNAL_AVX(cpu_flags)) {
|
||||
ASSIGN_VSCALEX_FUNC(c->yuv2planeX, avx, ,
|
||||
HAVE_ALIGNED_STACK || ARCH_X86_64);
|
||||
@@ -657,6 +666,7 @@ switch(c->dstBpc){ \
|
||||
break;
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
#if ARCH_X86_64
|
||||
#define ASSIGN_AVX2_SCALE_FUNC(hscalefn, filtersize) \
|
||||
@@ -666,6 +676,7 @@ switch(c->dstBpc){ \
|
||||
break; \
|
||||
}
|
||||
|
||||
+#if HAVE_AVX2_EXTERNAL
|
||||
if (EXTERNAL_AVX2_FAST(cpu_flags) && !(cpu_flags & AV_CPU_FLAG_SLOW_GATHER)) {
|
||||
if ((c->srcBpc == 8) && (c->dstBpc <= 14)) {
|
||||
ASSIGN_AVX2_SCALE_FUNC(c->hcScale, c->hChrFilterSize);
|
||||
@@ -697,6 +708,7 @@ switch(c->dstBpc){ \
|
||||
break;
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
|
||||
#define INPUT_PLANER_RGB_A_FUNC_CASE_NOBREAK(fmt, name, opt) \
|
||||
@@ -756,6 +768,7 @@ switch(c->dstBpc){ \
|
||||
INPUT_PLANER_RGBAXX_YUVA_FUNC_CASE(AV_PIX_FMT_GBRPF32, AV_PIX_FMT_GBRAPF32, rgbf32, opt)
|
||||
|
||||
|
||||
+#if HAVE_SSE2_EXTERNAL
|
||||
if (EXTERNAL_SSE2(cpu_flags)) {
|
||||
switch (c->opts.src_format) {
|
||||
INPUT_PLANER_RGB_A_FUNC_CASE_NOBREAK(AV_PIX_FMT_GBRAP, rgb, sse2);
|
||||
@@ -770,7 +783,9 @@ switch(c->dstBpc){ \
|
||||
break;
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
+#if HAVE_SSE4_EXTERNAL
|
||||
if (EXTERNAL_SSE4(cpu_flags)) {
|
||||
switch (c->opts.src_format) {
|
||||
case AV_PIX_FMT_GBRAP:
|
||||
@@ -785,7 +800,9 @@ switch(c->dstBpc){ \
|
||||
break;
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
+#if HAVE_AVX2_EXTERNAL
|
||||
if (EXTERNAL_AVX2_FAST(cpu_flags)) {
|
||||
switch (c->opts.src_format) {
|
||||
INPUT_PLANER_RGB_YUVA_ALL_CASES(avx2)
|
||||
@@ -793,6 +810,7 @@ switch(c->dstBpc){ \
|
||||
break;
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
if(c->opts.flags & SWS_FULL_CHR_H_INT) {
|
||||
|
||||
@@ -825,6 +843,7 @@ switch(c->dstBpc){ \
|
||||
YUV2ANYX_FUNC_CASE(AV_PIX_FMT_GBRPF32BE, gbrpf32be, opt) \
|
||||
YUV2ANYX_FUNC_CASE(AV_PIX_FMT_GBRAPF32BE, gbrapf32be, opt)
|
||||
|
||||
+#if HAVE_SSE2_EXTERNAL
|
||||
if (EXTERNAL_SSE2(cpu_flags)) {
|
||||
switch (c->opts.dst_format) {
|
||||
YUV2ANYX_GBRAP_CASES(sse2)
|
||||
@@ -832,7 +851,9 @@ switch(c->dstBpc){ \
|
||||
break;
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
+#if HAVE_SSE4_EXTERNAL
|
||||
if (EXTERNAL_SSE4(cpu_flags)) {
|
||||
switch (c->opts.dst_format) {
|
||||
YUV2ANYX_GBRAP_CASES(sse4)
|
||||
@@ -840,7 +861,9 @@ switch(c->dstBpc){ \
|
||||
break;
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
+#if HAVE_AVX2_EXTERNAL
|
||||
if (EXTERNAL_AVX2_FAST(cpu_flags)) {
|
||||
switch (c->opts.dst_format) {
|
||||
YUV2ANYX_GBRAP_CASES(avx2)
|
||||
@@ -848,7 +871,8 @@ switch(c->dstBpc){ \
|
||||
break;
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
}
|
||||
|
||||
-#endif
|
||||
+#endif /* ARCH_X86_64 */
|
||||
}
|
||||
--
|
||||
2.43.0.windows.1
|
||||
|
||||
@@ -105,7 +105,14 @@ jobs:
|
||||
|
||||
- name: Setup msbuild
|
||||
if: inputs.configuration != 'CMake'
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
|
||||
- name: Locate vcvars
|
||||
if: inputs.configuration == 'CMake'
|
||||
shell: cmd
|
||||
run: |
|
||||
for /f "usebackq tokens=*" %%i in (`call vswhere -latest -property installationPath`) do set "VSINSTPATH=%%i"
|
||||
echo VCVARSPATH=%VSINSTPATH%\VC\Auxiliary\Build\vcvars64.bat>>%GITHUB_ENV%
|
||||
|
||||
- name: Download patches
|
||||
shell: cmd
|
||||
@@ -124,6 +131,7 @@ jobs:
|
||||
if: steps.cache-deps.outputs.cache-hit != 'true'
|
||||
env:
|
||||
DEBUG: 0
|
||||
BUILD_FFMPEG: 1
|
||||
run: .github/workflows/scripts/windows/build-dependencies.bat
|
||||
|
||||
- name: Generate CMake
|
||||
@@ -131,30 +139,32 @@ jobs:
|
||||
id: cmake
|
||||
shell: cmd
|
||||
run: |
|
||||
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
call "%VCVARSPATH%" || exit /b
|
||||
cmake . -B build ${{ inputs.cmakeFlags }} "-DCMAKE_PREFIX_PATH=%cd%\deps" -DQT_BUILD=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DDISABLE_ADVANCE_SIMD=ON -G Ninja
|
||||
|
||||
- name: Build PCSX2
|
||||
shell: cmd
|
||||
run: |
|
||||
if "${{ inputs.configuration }}"=="CMake" (
|
||||
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
call "%VCVARSPATH%" || exit /b
|
||||
cmake --build build --config Release || exit /b
|
||||
cmake --install build --config Release || exit /b
|
||||
) else (
|
||||
msbuild "PCSX2_qt.sln" /m /v:m /p:Configuration="${{ inputs.configuration }}" /p:Platform="${{ inputs.platform }}"
|
||||
)
|
||||
REM We can use Segoe UI Emoji so we don't need to bundle this
|
||||
del bin\resources\fonts\NotoColorEmoji*
|
||||
|
||||
- name: Run Tests
|
||||
if: inputs.configuration == 'CMake'
|
||||
shell: cmd
|
||||
run: |
|
||||
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
call "%VCVARSPATH%" || exit /b
|
||||
set PATH=%PATH%;%GITHUB_WORKSPACE%\bin
|
||||
cmake --build build --config Release --target unittests
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
|
||||
path: |
|
||||
@@ -168,7 +178,7 @@ jobs:
|
||||
!./bin/**/*.lib
|
||||
|
||||
- name: Install the Breakpad Symbol Generator
|
||||
uses: baptiste0928/cargo-install@b687c656bda5733207e629b50a22bf68974a0305
|
||||
uses: baptiste0928/cargo-install@f204293d9709061b7bc1756fec3ec4e2cd57dec0
|
||||
with:
|
||||
crate: dump_syms
|
||||
|
||||
@@ -186,7 +196,7 @@ jobs:
|
||||
}
|
||||
|
||||
- name: Upload artifact - with symbols
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}-symbols
|
||||
path: |
|
||||
|
||||
Vendored
+9
-7
@@ -155,15 +155,17 @@ executable(
|
||||
|
||||
This project can be built using [Bazel](https://bazel.build/install).
|
||||
|
||||
You can also use this library as a dependency to your Bazel project. Add to the `WORKSPACE` file:
|
||||
You can also use this library as a dependency to your Bazel project. Add to your `MODULE.bazel` file:
|
||||
|
||||
```python
|
||||
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
|
||||
# fetch cpuinfo from Bazel Central Registry: https://registry.bazel.build/modules/cpuinfo
|
||||
bazel_dep(name = "cpuinfo", version = "0.0.0-20250925-877328f")
|
||||
|
||||
git_repository(
|
||||
name = "org_pytorch_cpuinfo",
|
||||
branch = "master",
|
||||
remote = "https://github.com/Vertexwahn/cpuinfo.git",
|
||||
# Optional: Override it with some specific commit hash
|
||||
git_override(
|
||||
module_name = "cpuinfo",
|
||||
commit = "<replace_with_commit_hash>"
|
||||
remote = "https://github.com/pytorch/cpuinfo.git",
|
||||
)
|
||||
```
|
||||
|
||||
@@ -176,7 +178,7 @@ cc_binary(
|
||||
# ...
|
||||
],
|
||||
deps = [
|
||||
"@org_pytorch_cpuinfo//:cpuinfo",
|
||||
"@cpuinfo",
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.18 FATAL_ERROR)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR)
|
||||
|
||||
PROJECT(googletest-download NONE)
|
||||
|
||||
INCLUDE(ExternalProject)
|
||||
ExternalProject_Add(googletest
|
||||
URL https://github.com/google/googletest/archive/refs/tags/v1.17.0.zip
|
||||
URL_HASH SHA256=40d4ec942217dcc84a9ebe2a68584ada7d4a33a8ee958755763278ea1c5e18ff
|
||||
URL https://github.com/google/googletest/archive/release-1.8.0.zip
|
||||
URL_HASH SHA256=f3ed3b58511efd272eb074a3a6d6fb79d7c2e6a0e374323d1e6bcbcc1ef141bf
|
||||
SOURCE_DIR "${CONFU_DEPENDENCIES_SOURCE_DIR}/googletest"
|
||||
BINARY_DIR "${CONFU_DEPENDENCIES_BINARY_DIR}/googletest"
|
||||
CONFIGURE_COMMAND ""
|
||||
|
||||
Vendored
+23
@@ -431,6 +431,8 @@ enum cpuinfo_uarch {
|
||||
cpuinfo_uarch_zen4 = 0x0020010C,
|
||||
/** AMD Zen 5 microarchitecture. */
|
||||
cpuinfo_uarch_zen5 = 0x0020010D,
|
||||
/** AMD Zen 6 microarchitecture. */
|
||||
cpuinfo_uarch_zen6 = 0x0020010E,
|
||||
|
||||
/** NSC Geode and AMD Geode GX and LX. */
|
||||
cpuinfo_uarch_geode = 0x00200200,
|
||||
@@ -526,6 +528,15 @@ enum cpuinfo_uarch {
|
||||
/** ARM Cortex-A725. */
|
||||
cpuinfo_uarch_cortex_a725 = 0x00300574,
|
||||
|
||||
/** ARM Lumex-C1-Ultra. */
|
||||
cpuinfo_uarch_lumex_c1_ultra = 0x00300600,
|
||||
/** ARM Lumex-C1-Premium. */
|
||||
cpuinfo_uarch_lumex_c1_premium = 0x00300601,
|
||||
/** ARM Lumex-C1-Pro. */
|
||||
cpuinfo_uarch_lumex_c1_pro = 0x00300602,
|
||||
/** ARM Lumex-C1-Nano. */
|
||||
cpuinfo_uarch_lumex_c1_nano = 0x00300603,
|
||||
|
||||
/** Qualcomm Scorpion. */
|
||||
cpuinfo_uarch_scorpion = 0x00400100,
|
||||
/** Qualcomm Krait. */
|
||||
@@ -538,6 +549,8 @@ enum cpuinfo_uarch {
|
||||
cpuinfo_uarch_saphira = 0x00400104,
|
||||
/** Qualcomm Oryon. */
|
||||
cpuinfo_uarch_oryon = 0x00400105,
|
||||
/** Qualcomm Oryon V3. */
|
||||
cpuinfo_uarch_oryon_v3 = 0x00400106,
|
||||
|
||||
/** Nvidia Denver. */
|
||||
cpuinfo_uarch_denver = 0x00500100,
|
||||
@@ -612,6 +625,16 @@ enum cpuinfo_uarch {
|
||||
/** Apple A18 pro processor (little cores). */
|
||||
cpuinfo_uarch_tahiti_sawtooth = 0x00700207,
|
||||
|
||||
/** Apple A19 processor (big cores). */
|
||||
cpuinfo_uarch_tilos_everest = 0x00700208,
|
||||
/** Apple A19 processor (little cores). */
|
||||
cpuinfo_uarch_tilos_sawtooth = 0x00700209,
|
||||
|
||||
/** Apple M4 processor (big cores). */
|
||||
cpuinfo_uarch_donan_everest = 0x00700308,
|
||||
/** Apple M4 processor (little cores). */
|
||||
cpuinfo_uarch_donan_sawtooth = 0x00700309,
|
||||
|
||||
/** Cavium ThunderX. */
|
||||
cpuinfo_uarch_thunderx = 0x00800100,
|
||||
/** Cavium ThunderX2 (originally Broadcom Vulkan). */
|
||||
|
||||
@@ -69,6 +69,7 @@ void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
|
||||
* - Processors with Cortex-A77 cores
|
||||
* - Processors with Cortex-A78 cores
|
||||
* - Processors with Cortex-A510 cores
|
||||
* - Processors with Cortex-A520 cores
|
||||
* - Processors with Cortex-A710 cores
|
||||
* - Processors with Cortex-A715 cores
|
||||
* - Processors with Cortex-X1 cores
|
||||
@@ -101,6 +102,7 @@ void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
|
||||
case UINT32_C(0x4100D470): /* Cortex-A710 */
|
||||
case UINT32_C(0x4100D480): /* Cortex-X2 */
|
||||
case UINT32_C(0x4100D490): /* Neoverse N2 */
|
||||
case UINT32_C(0x4100D4B0): /* Cortex-A78C */
|
||||
case UINT32_C(0x4100D4D0): /* Cortex-A715 */
|
||||
case UINT32_C(0x4100D4E0): /* Cortex-X3 */
|
||||
case UINT32_C(0x4100D4F0): /* Neoverse V2 */
|
||||
@@ -162,6 +164,7 @@ void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
|
||||
case UINT32_C(0x4100D470): /* Cortex-A710 */
|
||||
case UINT32_C(0x4100D480): /* Cortex-X2 */
|
||||
case UINT32_C(0x4100D490): /* Neoverse N2 */
|
||||
case UINT32_C(0x4100D4B0): /* Cortex-A78C */
|
||||
case UINT32_C(0x4100D4D0): /* Cortex-A715 */
|
||||
case UINT32_C(0x4100D4E0): /* Cortex-X3 */
|
||||
case UINT32_C(0x4100D4F0): /* Neoverse V2 */
|
||||
|
||||
+8
-8
@@ -1314,7 +1314,7 @@ static bool match_omap(const char* start, const char* end, struct cpuinfo_arm_ch
|
||||
* ro.board.platform) to match.
|
||||
* @param cores - number of cores in the chipset.
|
||||
* @param max_cpu_freq_max - maximum of
|
||||
* /sys/devices/system/cpu/cpu<number>/cpofreq/cpu_freq_max values.
|
||||
* /sys/devices/system/cpu/cpu<number>/cpufreq/cpu_freq_max values.
|
||||
* @param[out] chipset - location where chipset information will be stored upon
|
||||
* a successful match and decoding.
|
||||
*
|
||||
@@ -1607,7 +1607,7 @@ static bool match_and_parse_sunxi(
|
||||
* @param end - end of the /proc/cpuinfo Hardware string to match.
|
||||
* @param cores - number of cores in the chipset.
|
||||
* @param max_cpu_freq_max - maximum of
|
||||
* /sys/devices/system/cpu/cpu<number>/cpofreq/cpu_freq_max values.
|
||||
* /sys/devices/system/cpu/cpu<number>/cpufreq/cpu_freq_max values.
|
||||
* @param[out] chipset - location where chipset information will be stored upon
|
||||
* a successful match and decoding.
|
||||
*
|
||||
@@ -2456,7 +2456,7 @@ static const struct special_map_entry tegra_hardware_map_entries[] = {
|
||||
* @param[in] platform - /proc/cpuinfo Hardware string.
|
||||
* @param cores - number of cores in the chipset.
|
||||
* @param max_cpu_freq_max - maximum of
|
||||
* /sys/devices/system/cpu/cpu<number>/cpofreq/cpu_freq_max values.
|
||||
* /sys/devices/system/cpu/cpu<number>/cpufreq/cpu_freq_max values.
|
||||
*
|
||||
* @returns Decoded chipset name. If chipset could not be decoded, the resulting
|
||||
* structure would use `unknown` vendor and series identifiers.
|
||||
@@ -2857,7 +2857,7 @@ static const struct special_map_entry special_board_map_entries[] = {
|
||||
* @param[in] platform - ro.product.board value.
|
||||
* @param cores - number of cores in the chipset.
|
||||
* @param max_cpu_freq_max - maximum of
|
||||
* /sys/devices/system/cpu/cpu<number>/cpofreq/cpu_freq_max values.
|
||||
* /sys/devices/system/cpu/cpu<number>/cpufreq/cpu_freq_max values.
|
||||
*
|
||||
* @returns Decoded chipset name. If chipset could not be decoded, the resulting
|
||||
* structure would use `unknown` vendor and series identifiers.
|
||||
@@ -3162,7 +3162,7 @@ static const struct special_map_entry special_platform_map_entries[] = {
|
||||
* @param[in] platform - ro.board.platform value.
|
||||
* @param cores - number of cores in the chipset.
|
||||
* @param max_cpu_freq_max - maximum of
|
||||
* /sys/devices/system/cpu/cpu<number>/cpofreq/cpu_freq_max values.
|
||||
* /sys/devices/system/cpu/cpu<number>/cpufreq/cpu_freq_max values.
|
||||
*
|
||||
* @returns Decoded chipset name. If chipset could not be decoded, the resulting
|
||||
* structure would use `unknown` vendor and series identifiers.
|
||||
@@ -3499,7 +3499,7 @@ struct cpuinfo_arm_chipset cpuinfo_arm_android_decode_chipset_from_ro_chipname(
|
||||
* @param[in,out] chipset - chipset name to fix.
|
||||
* @param cores - number of cores in the chipset.
|
||||
* @param max_cpu_freq_max - maximum of
|
||||
* /sys/devices/system/cpu/cpu<number>/cpofreq/cpu_freq_max values.
|
||||
* /sys/devices/system/cpu/cpu<number>/cpufreq/cpu_freq_max values.
|
||||
*/
|
||||
void cpuinfo_arm_fixup_chipset(
|
||||
struct cpuinfo_arm_chipset chipset[restrict static 1],
|
||||
@@ -4038,7 +4038,7 @@ static enum cpuinfo_arm_chipset_vendor disambiguate_chipset_vendor(
|
||||
* described above.
|
||||
* @param cores - number of cores in the chipset.
|
||||
* @param max_cpu_freq_max - maximum of
|
||||
* /sys/devices/system/cpu/cpu<number>/cpofreq/cpu_freq_max values.
|
||||
* /sys/devices/system/cpu/cpu<number>/cpufreq/cpu_freq_max values.
|
||||
*
|
||||
* @returns Decoded chipset name. If chipset could not be decoded, the resulting
|
||||
* structure would use `unknown` vendor and series identifiers.
|
||||
@@ -4291,7 +4291,7 @@ void cpuinfo_arm_fixup_raspberry_pi_chipset(
|
||||
* @param[in] hardware - /proc/cpuinfo Hardware string.
|
||||
* @param cores - number of cores in the chipset.
|
||||
* @param max_cpu_freq_max - maximum of
|
||||
* /sys/devices/system/cpu/cpu<number>/cpofreq/cpu_freq_max values.
|
||||
* /sys/devices/system/cpu/cpu<number>/cpufreq/cpu_freq_max values.
|
||||
*
|
||||
* @returns Decoded chipset name. If chipset could not be decoded, the resulting
|
||||
* structure would use `unknown` vendor and series identifiers.
|
||||
|
||||
Vendored
+76
-67
@@ -21,9 +21,11 @@
|
||||
#ifndef CPUFAMILY_ARM_LIGHTNING_THUNDER
|
||||
#define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504D2
|
||||
#endif
|
||||
// A14 / M1
|
||||
#ifndef CPUFAMILY_ARM_FIRESTORM_ICESTORM
|
||||
#define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1B588BB3
|
||||
#endif
|
||||
// A15 / M2
|
||||
#ifndef CPUFAMILY_ARM_AVALANCHE_BLIZZARD
|
||||
#define CPUFAMILY_ARM_AVALANCHE_BLIZZARD 0xDA33D83D
|
||||
#endif
|
||||
@@ -66,6 +68,18 @@
|
||||
#ifndef CPUFAMILY_ARM_BRAVA
|
||||
#define CPUFAMILY_ARM_BRAVA 0x17d5b93a
|
||||
#endif
|
||||
// M5
|
||||
#ifndef CPUFAMILY_ARM_HIDRA
|
||||
#define CPUFAMILY_ARM_HIDRA 0x1d5a87e8
|
||||
#endif
|
||||
// A19
|
||||
#ifndef CPUFAMILY_ARM_TILOS
|
||||
#define CPUFAMILY_ARM_TILOS 0x01d7a72b
|
||||
#endif
|
||||
// A19 Pro
|
||||
#ifndef CPUFAMILY_ARM_THERA
|
||||
#define CPUFAMILY_ARM_THERA 0xab345f09
|
||||
#endif
|
||||
|
||||
struct cpuinfo_arm_isa cpuinfo_isa = {
|
||||
.aes = true,
|
||||
@@ -118,37 +132,59 @@ static enum cpuinfo_uarch decode_uarch(uint32_t cpu_family, uint32_t core_index,
|
||||
/* 2x Monsoon + 4x Mistral cores */
|
||||
return core_index < 2 ? cpuinfo_uarch_monsoon : cpuinfo_uarch_mistral;
|
||||
case CPUFAMILY_ARM_VORTEX_TEMPEST:
|
||||
/* Hexa-core: 2x Vortex + 4x Tempest; Octa-core: 4x
|
||||
* Cortex + 4x Tempest */
|
||||
/* Hexa-core: 2x Vortex + 4x Tempest; */
|
||||
/* Octa-core: 4x Cortex + 4x Tempest */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_vortex : cpuinfo_uarch_tempest;
|
||||
case CPUFAMILY_ARM_LIGHTNING_THUNDER:
|
||||
/* Hexa-core: 2x Lightning + 4x Thunder; Octa-core
|
||||
* (presumed): 4x Lightning + 4x Thunder */
|
||||
/* Hexa-core: 2x Lightning + 4x Thunder; */
|
||||
/* Octa-core: 4x Lightning + 4x Thunder */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_lightning : cpuinfo_uarch_thunder;
|
||||
case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
|
||||
/* Hexa-core: 2x Firestorm + 4x Icestorm; Octa-core: 4x
|
||||
* Firestorm + 4x Icestorm */
|
||||
/* Hexa-core: 2x Firestorm + 4x Icestorm; */
|
||||
/* Octa-core: 4x Firestorm + 4x Icestorm */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_firestorm : cpuinfo_uarch_icestorm;
|
||||
case CPUFAMILY_ARM_AVALANCHE_BLIZZARD:
|
||||
/* Hexa-core: 2x Avalanche + 4x Blizzard */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_avalanche : cpuinfo_uarch_blizzard;
|
||||
case CPUFAMILY_ARM_EVEREST_SAWTOOTH:
|
||||
/* Hexa-core: 2x Avalanche + 4x Blizzard */
|
||||
/* Hexa-core: 2x Everest + 4x Sawtooth */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_everest : cpuinfo_uarch_sawtooth;
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_avalanche : cpuinfo_uarch_blizzard;
|
||||
|
||||
case CPUFAMILY_ARM_IBIZA: /* M3 */
|
||||
/* 8-core: 4x Coll Everest v2 + 4x Coll Sawtooth v2*/
|
||||
case CPUFAMILY_ARM_PALMA: /* M3 Max */
|
||||
/* 14-core: 10x Coll Everest v2 + 4x Coll Sawtooth v2*/
|
||||
case CPUFAMILY_ARM_COLL:
|
||||
/* Hexa-core: 2x Avalanche + 4x Blizzard */
|
||||
/* Hexa-core: 2x Coll Everest v2 + 4x Coll Sawtooth v2 */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_coll_everest : cpuinfo_uarch_coll_sawtooth;
|
||||
case CPUFAMILY_ARM_LOBOS: /* M3 Pro */
|
||||
/* 12-core: 6x Coll Everest v2 + 6x Coll Sawtooth v2v2 */
|
||||
return core_index + 6 < core_count ? cpuinfo_uarch_coll_everest : cpuinfo_uarch_coll_sawtooth;
|
||||
|
||||
case CPUFAMILY_ARM_TUPAI:
|
||||
/* Hexa-core: 2x Avalanche + 4x Blizzard */
|
||||
/* Hexa-core: 2x Tupai Everest v3 + 4x Tupai Sawtooth v3 */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_tupai_everest : cpuinfo_uarch_tupai_sawtooth;
|
||||
|
||||
case CPUFAMILY_ARM_TAHITI:
|
||||
/* Hexa-core: 2x Avalanche + 4x Blizzard */
|
||||
/* Hexa-core: 2x Tahiti Everest + 4x Tahiti Sawtooth */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_tahiti_everest
|
||||
: cpuinfo_uarch_tahiti_sawtooth;
|
||||
|
||||
case CPUFAMILY_ARM_DONAN: /* M4 */
|
||||
/* 10-core: 4x Donan Everest v3 + 6x Donan Sawtooth v3 */
|
||||
return core_index + 6 < core_count ? cpuinfo_uarch_donan_everest : cpuinfo_uarch_donan_sawtooth;
|
||||
case CPUFAMILY_ARM_BRAVA: /* M4 Pro */
|
||||
/* 14-core: 10x Donan Everest v3 + 4x Donan Sawtooth v3 */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_donan_everest : cpuinfo_uarch_donan_sawtooth;
|
||||
|
||||
case CPUFAMILY_ARM_TILOS: /* A19 */
|
||||
case CPUFAMILY_ARM_THERA: /* A19 Pro */
|
||||
/* Hexa-core: 2x Tilos Everest v4 + 4x Tilos Sawtooth v4 */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_tilos_everest : cpuinfo_uarch_tilos_sawtooth;
|
||||
case CPUFAMILY_ARM_HIDRA: /* M5 */
|
||||
/* 10-core: 4x Tilos Everest v4 + 6x Tilos Sawtooth v4 */
|
||||
return core_index + 6 < core_count ? cpuinfo_uarch_tilos_everest : cpuinfo_uarch_tilos_sawtooth;
|
||||
|
||||
default:
|
||||
/* Use hw.cpusubtype for detection */
|
||||
break;
|
||||
@@ -361,10 +397,8 @@ void cpuinfo_arm_mach_init(void) {
|
||||
* possible. Otherwise, fallback to hardcoded set of CPUs with known
|
||||
* support.
|
||||
*/
|
||||
const uint32_t has_feat_lse = get_sys_info_by_name("hw.optional.arm.FEAT_LSE");
|
||||
if (has_feat_lse != 0) {
|
||||
cpuinfo_isa.atomics = true;
|
||||
} else {
|
||||
cpuinfo_isa.atomics = get_sys_info_by_name("hw.optional.arm.FEAT_LSE") != 0;
|
||||
if (!cpuinfo_isa.atomics) {
|
||||
// Mandatory in ARMv8.1-A, list only cores released before iOS
|
||||
// 15 / macOS 12
|
||||
switch (cpu_family) {
|
||||
@@ -376,10 +410,8 @@ void cpuinfo_arm_mach_init(void) {
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t has_feat_rdm = get_sys_info_by_name("hw.optional.arm.FEAT_RDM");
|
||||
if (has_feat_rdm != 0) {
|
||||
cpuinfo_isa.rdm = true;
|
||||
} else {
|
||||
cpuinfo_isa.rdm = get_sys_info_by_name("hw.optional.arm.FEAT_RDM") != 0;
|
||||
if (!cpuinfo_isa.rdm) {
|
||||
// Optional in ARMv8.2-A (implemented in Apple cores),
|
||||
// list only cores released before iOS 15 / macOS 12
|
||||
switch (cpu_family) {
|
||||
@@ -391,10 +423,8 @@ void cpuinfo_arm_mach_init(void) {
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t has_feat_fp16 = get_sys_info_by_name("hw.optional.arm.FEAT_FP16");
|
||||
if (has_feat_fp16 != 0) {
|
||||
cpuinfo_isa.fp16arith = true;
|
||||
} else {
|
||||
cpuinfo_isa.fp16arith = get_sys_info_by_name("hw.optional.arm.FEAT_FP16") != 0;
|
||||
if (!cpuinfo_isa.fp16arith) {
|
||||
// Optional in ARMv8.2-A (implemented in Apple cores),
|
||||
// list only cores released before iOS 15 / macOS 12
|
||||
switch (cpu_family) {
|
||||
@@ -406,15 +436,11 @@ void cpuinfo_arm_mach_init(void) {
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t has_feat_fhm = get_sys_info_by_name("hw.optional.arm.FEAT_FHM");
|
||||
if (has_feat_fhm != 0) {
|
||||
cpuinfo_isa.fhm = true;
|
||||
} else {
|
||||
cpuinfo_isa.fhm = get_sys_info_by_name("hw.optional.arm.FEAT_FHM") != 0;
|
||||
if (!cpuinfo_isa.fhm) {
|
||||
// Prior to iOS 15, use 'hw.optional.armv8_2_fhm'
|
||||
const uint32_t has_feat_fhm_legacy = get_sys_info_by_name("hw.optional.armv8_2_fhm");
|
||||
if (has_feat_fhm_legacy != 0) {
|
||||
cpuinfo_isa.fhm = true;
|
||||
} else {
|
||||
cpuinfo_isa.fhm = get_sys_info_by_name("hw.optional.armv8_2_fhm") != 0;
|
||||
if (!cpuinfo_isa.fhm) {
|
||||
// Mandatory in ARMv8.4-A when FP16 arithmetics is
|
||||
// implemented, list only cores released before iOS 15 /
|
||||
// macOS 12
|
||||
@@ -426,17 +452,10 @@ void cpuinfo_arm_mach_init(void) {
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t has_feat_bf16 = get_sys_info_by_name("hw.optional.arm.FEAT_BF16");
|
||||
if (has_feat_bf16 != 0) {
|
||||
cpuinfo_isa.bf16 = true;
|
||||
}
|
||||
|
||||
const uint32_t has_feat_fcma = get_sys_info_by_name("hw.optional.arm.FEAT_FCMA");
|
||||
if (has_feat_fcma != 0) {
|
||||
cpuinfo_isa.fcma = true;
|
||||
} else {
|
||||
// Mandatory in ARMv8.3-A, list only cores released before iOS
|
||||
// 15 / macOS 12
|
||||
cpuinfo_isa.bf16 = get_sys_info_by_name("hw.optional.arm.FEAT_BF16") != 0;
|
||||
cpuinfo_isa.fcma = get_sys_info_by_name("hw.optional.arm.FEAT_FCMA") != 0;
|
||||
if (!cpuinfo_isa.fcma) {
|
||||
// Mandatory in ARMv8.3-A, list only cores released before iOS 15 / macOS 12
|
||||
switch (cpu_family) {
|
||||
case CPUFAMILY_ARM_LIGHTNING_THUNDER:
|
||||
case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
|
||||
@@ -444,12 +463,9 @@ void cpuinfo_arm_mach_init(void) {
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t has_feat_jscvt = get_sys_info_by_name("hw.optional.arm.FEAT_JSCVT");
|
||||
if (has_feat_jscvt != 0) {
|
||||
cpuinfo_isa.jscvt = true;
|
||||
} else {
|
||||
// Mandatory in ARMv8.3-A, list only cores released before iOS
|
||||
// 15 / macOS 12
|
||||
cpuinfo_isa.jscvt = get_sys_info_by_name("hw.optional.arm.FEAT_JSCVT") != 0;
|
||||
if (!cpuinfo_isa.jscvt) {
|
||||
// Mandatory in ARMv8.3-A, list only cores released before iOS 15 / macOS 12
|
||||
switch (cpu_family) {
|
||||
case CPUFAMILY_ARM_LIGHTNING_THUNDER:
|
||||
case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
|
||||
@@ -457,12 +473,9 @@ void cpuinfo_arm_mach_init(void) {
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t has_feat_dotprod = get_sys_info_by_name("hw.optional.arm.FEAT_DotProd");
|
||||
if (has_feat_dotprod != 0) {
|
||||
cpuinfo_isa.dot = true;
|
||||
} else {
|
||||
// Mandatory in ARMv8.4-A, list only cores released before iOS
|
||||
// 15 / macOS 12
|
||||
cpuinfo_isa.dot = get_sys_info_by_name("hw.optional.arm.FEAT_DotProd") != 0;
|
||||
if (!cpuinfo_isa.dot) {
|
||||
// Mandatory in ARMv8.4-A, list only cores released before iOS 15 / macOS 12
|
||||
switch (cpu_family) {
|
||||
case CPUFAMILY_ARM_LIGHTNING_THUNDER:
|
||||
case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
|
||||
@@ -470,20 +483,16 @@ void cpuinfo_arm_mach_init(void) {
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t has_feat_i8mm = get_sys_info_by_name("hw.optional.arm.FEAT_I8MM");
|
||||
if (has_feat_i8mm != 0) {
|
||||
cpuinfo_isa.i8mm = true;
|
||||
}
|
||||
cpuinfo_isa.i8mm = get_sys_info_by_name("hw.optional.arm.FEAT_I8MM") != 0;
|
||||
cpuinfo_isa.sme = get_sys_info_by_name("hw.optional.arm.FEAT_SME") != 0;
|
||||
cpuinfo_isa.sme2 = get_sys_info_by_name("hw.optional.arm.FEAT_SME2") != 0;
|
||||
cpuinfo_isa.sme2p1 = get_sys_info_by_name("hw.optional.arm.FEAT_SME2p1") != 0;
|
||||
cpuinfo_isa.sme_i16i32 = get_sys_info_by_name("hw.optional.arm.SME_I16I32") != 0;
|
||||
cpuinfo_isa.sme_bi32i32 = get_sys_info_by_name("hw.optional.arm.SME_BI32I32") != 0;
|
||||
cpuinfo_isa.sme_b16b16 = get_sys_info_by_name("hw.optional.arm.FEAT_SME_B16B16") != 0;
|
||||
cpuinfo_isa.sme_f16f16 = get_sys_info_by_name("hw.optional.arm.FEAT_SME_F16F16") != 0;
|
||||
|
||||
const uint32_t has_feat_sme = get_sys_info_by_name("hw.optional.arm.FEAT_SME");
|
||||
if (has_feat_sme != 0) {
|
||||
cpuinfo_isa.sme = true;
|
||||
}
|
||||
|
||||
const uint32_t has_feat_sme2 = get_sys_info_by_name("hw.optional.arm.FEAT_SME2");
|
||||
if (has_feat_sme2 != 0) {
|
||||
cpuinfo_isa.sme2 = true;
|
||||
}
|
||||
cpuinfo_isa.smelen = get_sys_info_by_name("hw.optional.arm.sme_max_svl_b");
|
||||
|
||||
uint32_t num_clusters = 1;
|
||||
for (uint32_t i = 0; i < mach_topology.cores; i++) {
|
||||
|
||||
Vendored
+4
@@ -192,6 +192,7 @@ inline static uint32_t midr_score_core(uint32_t midr) {
|
||||
case UINT32_C(0x4100D0D0): /* Cortex-A77 */
|
||||
case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
|
||||
case UINT32_C(0x4100D410): /* Cortex-A78 */
|
||||
case UINT32_C(0x4100D4B0): /* Cortex-A78C */
|
||||
case UINT32_C(0x4100D470): /* Cortex-A710 */
|
||||
case UINT32_C(0x4100D4D0): /* Cortex-A715 */
|
||||
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
|
||||
@@ -220,6 +221,9 @@ inline static uint32_t midr_score_core(uint32_t midr) {
|
||||
case UINT32_C(0x4100D030): /* Cortex-A53 */
|
||||
case UINT32_C(0x4100D050): /* Cortex-A55 */
|
||||
case UINT32_C(0x4100D460): /* Cortex-A510 */
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
case UINT32_C(0x4100D800): /* Cortex-A520 */
|
||||
#endif /* CPUINFO_ARCH_ARM64 */
|
||||
/* Cortex-A53 is usually in LITTLE role, but can be in
|
||||
* big role w.r.t. Cortex-A35 */
|
||||
return 2;
|
||||
|
||||
Vendored
+19
@@ -94,6 +94,7 @@ void cpuinfo_arm_decode_vendor_uarch(
|
||||
*uarch = cpuinfo_uarch_neoverse_v1;
|
||||
break;
|
||||
case 0xD41: /* Cortex-A78 */
|
||||
case 0xD4B: /* Cortex-A78C */
|
||||
*uarch = cpuinfo_uarch_cortex_a78;
|
||||
break;
|
||||
case 0xD44: /* Cortex-X1 */
|
||||
@@ -125,6 +126,9 @@ void cpuinfo_arm_decode_vendor_uarch(
|
||||
case 0xD4F: /* Neoverse V2 */
|
||||
*uarch = cpuinfo_uarch_neoverse_v2;
|
||||
break;
|
||||
case 0xD80: /* Cortex-A520 */
|
||||
*uarch = cpuinfo_uarch_cortex_a520;
|
||||
break;
|
||||
case 0xD81: /* Cortex-A720 */
|
||||
*uarch = cpuinfo_uarch_cortex_a720;
|
||||
break;
|
||||
@@ -137,6 +141,18 @@ void cpuinfo_arm_decode_vendor_uarch(
|
||||
case 0xD87: /* Cortex-A725 */
|
||||
*uarch = cpuinfo_uarch_cortex_a725;
|
||||
break;
|
||||
case 0xD8C:
|
||||
*uarch = cpuinfo_uarch_lumex_c1_ultra;
|
||||
break;
|
||||
case 0xD90:
|
||||
*uarch = cpuinfo_uarch_lumex_c1_premium;
|
||||
break;
|
||||
case 0xD8B:
|
||||
*uarch = cpuinfo_uarch_lumex_c1_pro;
|
||||
break;
|
||||
case 0xD8A:
|
||||
*uarch = cpuinfo_uarch_lumex_c1_nano;
|
||||
break;
|
||||
default:
|
||||
switch (midr_get_part(midr) >> 8) {
|
||||
#if CPUINFO_ARCH_ARM
|
||||
@@ -347,6 +363,9 @@ void cpuinfo_arm_decode_vendor_uarch(
|
||||
case 0x001:
|
||||
*uarch = cpuinfo_uarch_oryon;
|
||||
break;
|
||||
case 0x002:
|
||||
*uarch = cpuinfo_uarch_oryon_v3;
|
||||
break;
|
||||
case 0xC00:
|
||||
*uarch = cpuinfo_uarch_falkor;
|
||||
break;
|
||||
|
||||
+8
@@ -249,6 +249,14 @@ static void set_cpuinfo_isa_fields(void) {
|
||||
// guarantee that, but it holds in practice.
|
||||
cpuinfo_isa.rdm = dotprod;
|
||||
|
||||
// PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE may not be available in older
|
||||
// Windows versions. If fp16arith was not detected with
|
||||
// IsProcessorFeaturePresent(PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE), fall
|
||||
// back to using the value of dotprod.
|
||||
if (!cpuinfo_isa.fp16arith) {
|
||||
cpuinfo_isa.fp16arith = dotprod;
|
||||
}
|
||||
|
||||
/* Windows API reports all or nothing for cryptographic instructions. */
|
||||
const bool crypto = IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
cpuinfo_isa.aes = crypto;
|
||||
|
||||
+1
-1
@@ -231,7 +231,7 @@ uint32_t cpuinfo_linux_get_processor_min_frequency(uint32_t processor) {
|
||||
}
|
||||
|
||||
bool cpuinfo_linux_get_processor_core_id(uint32_t processor, uint32_t core_id_ptr[restrict static 1]) {
|
||||
char core_id_filename[PACKAGE_ID_FILENAME_SIZE];
|
||||
char core_id_filename[CORE_ID_FILENAME_SIZE];
|
||||
const int chars_formatted =
|
||||
snprintf(core_id_filename, CORE_ID_FILENAME_SIZE, CORE_ID_FILENAME_FORMAT, processor);
|
||||
if ((unsigned int)chars_formatted >= CORE_ID_FILENAME_SIZE) {
|
||||
|
||||
Vendored
+2
@@ -612,6 +612,8 @@ uint32_t cpuinfo_x86_normalize_brand_string(const char raw_name[48], char normal
|
||||
break;
|
||||
case '@':
|
||||
parser_state.frequency_separator = char_ptr;
|
||||
*char_ptr = ' ';
|
||||
break;
|
||||
case '\0':
|
||||
case '\t':
|
||||
*char_ptr = ' ';
|
||||
|
||||
Vendored
+15
-1
@@ -402,7 +402,21 @@ enum cpuinfo_uarch cpuinfo_x86_decode_uarch(
|
||||
}
|
||||
break;
|
||||
case 0x1a:
|
||||
return cpuinfo_uarch_zen5;
|
||||
switch (model_info->extended_model) {
|
||||
case 0x0: // model 00h..2Fh
|
||||
case 0x1:
|
||||
case 0x2:
|
||||
case 0x4: // model 40h..4Fh
|
||||
return cpuinfo_uarch_zen5;
|
||||
|
||||
case 0x5: // model 50h..5Fh
|
||||
case 0x8: // model 80h..AFh
|
||||
case 0x9:
|
||||
case 0xA:
|
||||
case 0xC: // model C0h..CFh
|
||||
return cpuinfo_uarch_zen6;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case cpuinfo_vendor_hygon:
|
||||
|
||||
Vendored
+11
@@ -1,3 +1,14 @@
|
||||
# 3.1.0 (2026-02-23)
|
||||
|
||||
- Added supported for resource tight alignment (feature added in Agility SDK 1.618.1). It is used automatically when available.
|
||||
- Added function `Allocator::IsTightAlignmentSupported`.
|
||||
- Added `ALLOCATOR_FLAG_DONT_USE_TIGHT_ALIGNMENT`.
|
||||
- Fixes and improvements in the internal function `AllocatorPimpl::GetResourceAllocationInfo` (which decides when to use small alignment or tight alignment), including:
|
||||
- Added support for 1D and 3D textures when `D3D12MA_USE_SMALL_RESOURCE_PLACEMENT_ALIGNMENT = 2` (#78, #79).
|
||||
- Fix for cases when `D3D12_TEXTURE_LAYOUT_64KB_*_SWIZZLE` is used (#86).
|
||||
- Fixes for build errors in MinGW (#77).
|
||||
- Fixes and improvements in documentation and tests.
|
||||
|
||||
# 3.0.1 (2025-05-08)
|
||||
|
||||
- Fixed macros `D3D12MA_RECOMMENDED_ALLOCATOR_FLAGS`, `D3D12MA_RECOMMENDED_POOL_FLAGS` (#73).
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2019-2025 Advanced Micro Devices, Inc. All rights reserved.
|
||||
Copyright (c) 2019-2026 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
Vendored
+1
-1
@@ -8,7 +8,7 @@ Easy to integrate memory allocation library for Direct3D 12.
|
||||
|
||||
**Changelog:** See [CHANGELOG.md](CHANGELOG.md)
|
||||
|
||||
**Product page:** [D3D12 Memory Allocator on GPUOpen](https://gpuopen.com/gaming-product/d3d12-memory-allocator/)
|
||||
**Product page:** [D3D12 Memory Allocator on GPUOpen](https://gpuopen.com/d3d12-memory-allocator/)
|
||||
|
||||
[](http://isitmaintained.com/project/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator "Average time to resolve an issue")
|
||||
|
||||
|
||||
+42
-6
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2019-2025 Advanced Micro Devices, Inc. All rights reserved.
|
||||
// Copyright (c) 2019-2026 Advanced Micro Devices, Inc. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -24,9 +24,9 @@
|
||||
|
||||
/** \mainpage D3D12 Memory Allocator
|
||||
|
||||
<b>Version 3.0.1</b> (2025-05-08)
|
||||
<b>Version 3.1.0</b> (2026-02-23)
|
||||
|
||||
Copyright (c) 2019-2025 Advanced Micro Devices, Inc. All rights reserved. \n
|
||||
Copyright (c) 2019-2026 Advanced Micro Devices, Inc. All rights reserved. \n
|
||||
License: MIT
|
||||
|
||||
Documentation of all members: D3D12MemAlloc.h
|
||||
@@ -64,7 +64,7 @@ Documentation of all members: D3D12MemAlloc.h
|
||||
|
||||
\section main_see_also Web links
|
||||
|
||||
- [Direct3D 12 Memory Allocator at GPUOpen.com](https://gpuopen.com/gaming-product/d3d12-memory-allocator/) - product page
|
||||
- [Direct3D 12 Memory Allocator at GPUOpen.com](https://gpuopen.com/d3d12-memory-allocator/) - product page
|
||||
- [GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator at GitHub.com](https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator) - source code repository
|
||||
*/
|
||||
|
||||
@@ -1112,8 +1112,19 @@ enum ALLOCATOR_FLAGS
|
||||
which may take longer than creating placed resources in existing heaps.
|
||||
Passing this flag will disable this committed preference globally for the allocator.
|
||||
It can also be disabled for a single allocation by using #ALLOCATION_FLAG_STRATEGY_MIN_TIME.
|
||||
|
||||
If the tight resource alignment feature is used by the library (which happens automatically whenever supported,
|
||||
unless you use flag #ALLOCATOR_FLAG_DONT_USE_TIGHT_ALIGNMENT), then small buffers are not preferred as committed.
|
||||
Long story short, you don't need to specify any of these flags.
|
||||
The library chooses the most optimal method automatically.
|
||||
*/
|
||||
ALLOCATOR_FLAG_DONT_PREFER_SMALL_BUFFERS_COMMITTED = 0x10,
|
||||
/** Disables the use of the tight alignment feature even when it is supported on the current system.
|
||||
By default, the feature is used whenever available.
|
||||
|
||||
Support can be checked by D3D12MA::Allocator::IsTightAlignmentSupported() regardless of using this flag.
|
||||
*/
|
||||
ALLOCATOR_FLAG_DONT_USE_TIGHT_ALIGNMENT = 0x20,
|
||||
};
|
||||
|
||||
/// \brief Parameters of created Allocator object. To be used with CreateAllocator().
|
||||
@@ -1189,6 +1200,12 @@ public:
|
||||
This flag is fetched from `D3D12_FEATURE_D3D12_OPTIONS16::GPUUploadHeapSupported`.
|
||||
*/
|
||||
BOOL IsGPUUploadHeapSupported() const;
|
||||
/** \brief Returns true if resource tight alignment is supported on the current system.
|
||||
When supported, it is automatically used by the library, unless
|
||||
#ALLOCATOR_FLAG_DONT_USE_TIGHT_ALIGNMENT flag was specified on allocator creation.
|
||||
This flag is fetched from `D3D12_FEATURE_DATA_TIGHT_ALIGNMENT::SupportTier`.
|
||||
*/
|
||||
BOOL IsTightAlignmentSupported() const;
|
||||
/** \brief Returns total amount of memory of specific segment group, in bytes.
|
||||
|
||||
\param memorySegmentGroup use `DXGI_MEMORY_SEGMENT_GROUP_LOCAL` or `DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL`.
|
||||
@@ -1800,7 +1817,7 @@ DEFINE_ENUM_FLAG_OPERATORS(D3D12MA::VIRTUAL_ALLOCATION_FLAGS);
|
||||
/// \endcond
|
||||
|
||||
/**
|
||||
\page faq Frequenty asked questions
|
||||
\page faq Frequently asked questions
|
||||
|
||||
<b>What is %D3D12MA?</b>
|
||||
|
||||
@@ -2864,6 +2881,23 @@ and D3D12MA::POOL_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED on the creation of any cus
|
||||
With those flags, the alignment of the heaps created by %D3D12MA can be lower, but any MSAA textures are created as committed.
|
||||
You should always use these flags in your code unless you really need to create some MSAA textures as placed.
|
||||
|
||||
With DirectX 12 Agility SDK 1.618.1, Microsoft added a new feature called **"tight alignment"**.
|
||||
Note this is a separate feature than the "small alignment" described earlier.
|
||||
When using this new SDK and a compatible graphics driver, the API exposes support for this new feature.
|
||||
Then, a new flag `D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT` can be added when creating a resource.
|
||||
D3D12 can then return the alignment required for the resource smaller than the default ones described above.
|
||||
This library automatically makes use of the tight alignment feature when available and adds that new resource flag.
|
||||
When the tight alignment is enabled, the heuristics that creates small buffers as committed described above is deactivated,
|
||||
as it is no longer needed.
|
||||
|
||||
You can check if the tight alignment it is available in the current system by calling D3D12MA::Allocator::IsTightAlignmentSupported().
|
||||
You can tell the library to not use it by specifying D3D12MA::ALLOCATOR_FLAG_DONT_USE_TIGHT_ALIGNMENT.
|
||||
Typically, you don't need to do any of those.
|
||||
|
||||
The library automatically aligns all buffers to at least 256 B, even when the system supports smaller alignment.
|
||||
This is the alignment required for constant buffers, expressed by `D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT` constant.
|
||||
You can override this logic for \subpage custom_pools with a specific D3D12MA::POOL_DESC::MinAllocationAlignment.
|
||||
|
||||
\page defragmentation Defragmentation
|
||||
|
||||
Interleaved allocations and deallocations of many objects of varying size can
|
||||
@@ -3558,7 +3592,7 @@ Features deliberately excluded from the scope of this library:
|
||||
- **Descriptor allocation.** Although also called "heaps", objects that represent
|
||||
descriptors are separate part of the D3D12 API from buffers and textures.
|
||||
You can still use \ref virtual_allocator to manage descriptors and their ranges inside a descriptor heap.
|
||||
- **Support for reserved (tiled) resources.** We don't recommend using them.
|
||||
- **Support for reserved (tiled) resources.** We don't recommend using them. For more information, see [1].
|
||||
- Support for `ID3D12Device::Evict` and `MakeResident`. We don't recommend using them.
|
||||
You can call them on the D3D12 objects manually.
|
||||
Plese keep in mind, however, that eviction happens on the level of entire `ID3D12Heap` memory blocks
|
||||
@@ -3575,4 +3609,6 @@ Features deliberately excluded from the scope of this library:
|
||||
It is recommended to disable such warnings instead.
|
||||
- This is a C++ library. **Bindings or ports to any other programming languages** are welcome as external projects but
|
||||
are not going to be included into this repository.
|
||||
|
||||
[1] Antoine Richermoz, Fabrice Neyret. The Sad State of Hardware Virtual Textures. UGA - Universite Grenoble Alpes; INRIA Grenoble - Rhone-Alpes. 2025, pp.13. hal-05138369
|
||||
*/
|
||||
|
||||
+104
-21
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2019-2025 Advanced Micro Devices, Inc. All rights reserved.
|
||||
// Copyright (c) 2019-2026 Advanced Micro Devices, Inc. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -33,11 +33,24 @@
|
||||
#include <shared_mutex>
|
||||
#endif
|
||||
|
||||
// Includes needed for MinGW - see #71.
|
||||
#ifndef _MSC_VER
|
||||
#include <guiddef.h>
|
||||
// guiddef.h must be included first.
|
||||
#include <dxguids.h>
|
||||
// On older mingw versions, using the Agility SDK will cause linker errors unless dxguids.h is included.
|
||||
// But on newer mingw versions, the includes aren't necessary thus no need to grab DirectX-Headers.
|
||||
// Release cycles are slow for LTS distros on Linux, so this codeblock will need to stay for a few years.
|
||||
#if defined(__MINGW64_VERSION_MAJOR) && defined(__MINGW64_VERSION_MINOR) && \
|
||||
defined(__MINGW64_VERSION_BUGFIX) && defined(__ID3D12Device8_INTERFACE_DEFINED__)
|
||||
#define D3D12MA_MAKE_MINGW_VERSION(x, y, z) ((x << 20u) | (y << 10u) | (z))
|
||||
#if D3D12MA_MAKE_MINGW_VERSION(__MINGW64_VERSION_MAJOR, __MINGW64_VERSION_MINOR, \
|
||||
__MINGW64_VERSION_BUGFIX) <= D3D12MA_MAKE_MINGW_VERSION(11, 0, 1)
|
||||
#if defined(__has_include)
|
||||
#if !__has_include(<dxguids.h>)
|
||||
#error "mingw or gcc detected. dxguids.h is needed. You can grab it from https://github.com/microsoft/DirectX-Headers or if you're on Ubuntu just run sudo apt install directx-headers-dev"
|
||||
#endif
|
||||
#endif
|
||||
#include <guiddef.h>
|
||||
// // guiddef.h must be included first.
|
||||
#include <dxguids.h>
|
||||
#endif
|
||||
#undef D3D12MA_MAKE_MINGW_VERSION
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -93,6 +106,14 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef D3D12MA_DEFAULT_ALIGNMENT
|
||||
/*
|
||||
Default alignment of allocations in default pools and custom pools with MinAllocationAlignment == 0.
|
||||
Can be lowered for custom pools by specifying custom MinAllocationAlignment > 0.
|
||||
*/
|
||||
#define D3D12MA_DEFAULT_ALIGNMENT D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT
|
||||
#endif
|
||||
|
||||
#ifndef D3D12MA_DEBUG_ALIGNMENT
|
||||
/*
|
||||
Minimum alignment of all allocations, in bytes.
|
||||
@@ -126,6 +147,14 @@ especially to test compatibility with D3D12_RESOURCE_HEAP_TIER_1 on modern GPUs.
|
||||
#define D3D12MA_DEFAULT_BLOCK_SIZE (64ull * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
#ifndef D3D12MA_TIGHT_ALIGNMENT_SUPPORTED
|
||||
#if D3D12_SDK_VERSION >= 618
|
||||
#define D3D12MA_TIGHT_ALIGNMENT_SUPPORTED 1
|
||||
#else
|
||||
#define D3D12MA_TIGHT_ALIGNMENT_SUPPORTED 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef D3D12MA_OPTIONS16_SUPPORTED
|
||||
#if D3D12_SDK_VERSION >= 610
|
||||
#define D3D12MA_OPTIONS16_SUPPORTED 1
|
||||
@@ -186,6 +215,7 @@ static const D3D12_HEAP_FLAGS RESOURCE_CLASS_HEAP_FLAGS =
|
||||
static const D3D12_RESIDENCY_PRIORITY D3D12_RESIDENCY_PRIORITY_NONE = D3D12_RESIDENCY_PRIORITY(0);
|
||||
|
||||
static const D3D12_HEAP_TYPE D3D12_HEAP_TYPE_GPU_UPLOAD_COPY = (D3D12_HEAP_TYPE)5;
|
||||
static const D3D12_RESOURCE_FLAGS D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT_COPY = (D3D12_RESOURCE_FLAGS)0x400;
|
||||
|
||||
#ifndef _D3D12MA_ENUM_DECLARATIONS
|
||||
|
||||
@@ -787,11 +817,9 @@ static bool ValidateAllocateMemoryParameters(
|
||||
return pAllocDesc &&
|
||||
pAllocInfo &&
|
||||
ppAllocation &&
|
||||
(pAllocInfo->Alignment == 0 ||
|
||||
pAllocInfo->Alignment == D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT ||
|
||||
pAllocInfo->Alignment == D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT) &&
|
||||
pAllocInfo->SizeInBytes != 0 &&
|
||||
pAllocInfo->SizeInBytes % (64ull * 1024) == 0;
|
||||
IsPow2(pAllocInfo->Alignment) &&
|
||||
pAllocInfo->SizeInBytes > 0 &&
|
||||
pAllocInfo->SizeInBytes % 4 == 0;
|
||||
}
|
||||
|
||||
#endif // _D3D12MA_FUNCTIONS
|
||||
@@ -5960,6 +5988,8 @@ public:
|
||||
BOOL IsCacheCoherentUMA() const { return m_D3D12Architecture.CacheCoherentUMA; }
|
||||
bool SupportsResourceHeapTier2() const { return m_D3D12Options.ResourceHeapTier >= D3D12_RESOURCE_HEAP_TIER_2; }
|
||||
bool IsGPUUploadHeapSupported() const { return m_GPUUploadHeapSupported != FALSE; }
|
||||
bool IsTightAlignmentSupported() const { return m_TightAlignmentSupported != FALSE; }
|
||||
bool IsTightAlignmentEnabled() const { return IsTightAlignmentSupported() && m_UseTightAlignment; }
|
||||
bool UseMutex() const { return m_UseMutex; }
|
||||
AllocationObjectAllocator& GetAllocationObjectAllocator() { return m_AllocationObjectAllocator; }
|
||||
UINT GetCurrentFrameIndex() const { return m_CurrentFrameIndex.load(); }
|
||||
@@ -6046,7 +6076,8 @@ private:
|
||||
const bool m_UseMutex;
|
||||
const bool m_AlwaysCommitted;
|
||||
const bool m_MsaaAlwaysCommitted;
|
||||
const bool m_PreferSmallBuffersCommitted;
|
||||
bool m_PreferSmallBuffersCommitted;
|
||||
const bool m_UseTightAlignment;
|
||||
bool m_DefaultPoolsNotZeroed = false;
|
||||
ID3D12Device* m_Device; // AddRef
|
||||
#ifdef __ID3D12Device1_INTERFACE_DEFINED__
|
||||
@@ -6074,6 +6105,7 @@ private:
|
||||
DXGI_ADAPTER_DESC m_AdapterDesc;
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS m_D3D12Options;
|
||||
BOOL m_GPUUploadHeapSupported = FALSE;
|
||||
BOOL m_TightAlignmentSupported = FALSE;
|
||||
D3D12_FEATURE_DATA_ARCHITECTURE m_D3D12Architecture;
|
||||
AllocationObjectAllocator m_AllocationObjectAllocator;
|
||||
|
||||
@@ -6155,7 +6187,8 @@ AllocatorPimpl::AllocatorPimpl(const ALLOCATION_CALLBACKS& allocationCallbacks,
|
||||
: m_UseMutex((desc.Flags & ALLOCATOR_FLAG_SINGLETHREADED) == 0),
|
||||
m_AlwaysCommitted((desc.Flags & ALLOCATOR_FLAG_ALWAYS_COMMITTED) != 0),
|
||||
m_MsaaAlwaysCommitted((desc.Flags & ALLOCATOR_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED) != 0),
|
||||
m_PreferSmallBuffersCommitted((desc.Flags & ALLOCATOR_FLAG_DONT_PREFER_SMALL_BUFFERS_COMMITTED) == 0),
|
||||
m_PreferSmallBuffersCommitted((desc.Flags& ALLOCATOR_FLAG_DONT_PREFER_SMALL_BUFFERS_COMMITTED) == 0),
|
||||
m_UseTightAlignment((desc.Flags & ALLOCATOR_FLAG_DONT_USE_TIGHT_ALIGNMENT) == 0),
|
||||
m_Device(desc.pDevice),
|
||||
m_Adapter(desc.pAdapter),
|
||||
m_PreferredBlockSize(desc.PreferredBlockSize != 0 ? desc.PreferredBlockSize : D3D12MA_DEFAULT_BLOCK_SIZE),
|
||||
@@ -6244,6 +6277,25 @@ HRESULT AllocatorPimpl::Init(const ALLOCATOR_DESC& desc)
|
||||
}
|
||||
#endif // #if D3D12MA_OPTIONS16_SUPPORTED
|
||||
|
||||
#if D3D12MA_TIGHT_ALIGNMENT_SUPPORTED
|
||||
{
|
||||
D3D12_FEATURE_DATA_TIGHT_ALIGNMENT tightAlignment = {};
|
||||
hr = m_Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_TIGHT_ALIGNMENT, &tightAlignment, sizeof(tightAlignment));
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
m_TightAlignmentSupported = tightAlignment.SupportTier >= D3D12_TIGHT_ALIGNMENT_TIER_1;
|
||||
|
||||
// If tight alignment is supported (checked by the code above) and wasn't disabled by the developer
|
||||
// (with ALLOCATOR_FLAG_DONT_USE_TIGHT_ALIGNMENT), disable the preference for creating small buffers as committed,
|
||||
// as if ALLOCATOR_FLAG_DONT_PREFER_SMALL_BUFFERS_COMMITTED was specified.
|
||||
if (IsTightAlignmentEnabled())
|
||||
{
|
||||
m_PreferSmallBuffersCommitted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // #if D3D12MA_TIGHT_ALIGNMENT_SUPPORTED
|
||||
|
||||
hr = m_Device->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE, &m_D3D12Architecture, sizeof(m_D3D12Architecture));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
@@ -6273,7 +6325,7 @@ HRESULT AllocatorPimpl::Init(const ALLOCATOR_DESC& desc)
|
||||
0, // minBlockCount
|
||||
SIZE_MAX, // maxBlockCount
|
||||
false, // explicitBlockSize
|
||||
D3D12MA_DEBUG_ALIGNMENT, // minAllocationAlignment
|
||||
(UINT64)D3D12MA_DEFAULT_ALIGNMENT, // minAllocationAlignment
|
||||
0, // Default algorithm,
|
||||
m_MsaaAlwaysCommitted,
|
||||
NULL, // pProtectedSession
|
||||
@@ -6940,6 +6992,9 @@ void AllocatorPimpl::BuildStatsString(WCHAR** ppStatsString, BOOL detailedMap)
|
||||
|
||||
json.WriteString(L"GPUUploadHeapSupported");
|
||||
json.WriteBool(m_GPUUploadHeapSupported != FALSE);
|
||||
|
||||
json.WriteString(L"TightAlignmentSupported");
|
||||
json.WriteBool(m_TightAlignmentSupported != FALSE);
|
||||
}
|
||||
json.EndObject();
|
||||
}
|
||||
@@ -7758,8 +7813,24 @@ HRESULT AllocatorPimpl::GetResourceAllocationInfo(
|
||||
D3D12_RESOURCE_ALLOCATION_INFO& outAllocInfo) const
|
||||
{
|
||||
#ifdef __ID3D12Device1_INTERFACE_DEFINED__
|
||||
/* Optional optimization: Microsoft documentation says:
|
||||
https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-getresourceallocationinfo
|
||||
|
||||
#if D3D12MA_TIGHT_ALIGNMENT_SUPPORTED
|
||||
if (IsTightAlignmentEnabled())
|
||||
{
|
||||
// Don't allow USE_TIGHT_ALIGNMENT together with ALLOW_CROSS_ADAPTER as there is a D3D Debug Layer error:
|
||||
// D3D12 ERROR: ID3D12Device::GetResourceAllocationInfo: D3D12_RESOURCE_DESC::Flag D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT will be ignored since D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER is set. [ STATE_CREATION ERROR #599: CREATERESOURCE_INVALIDMISCFLAGS]
|
||||
// Also don't allow it together with D3D12_TEXTURE_LAYOUT_64KB_*_SWIZZLE, as there is this error (see issue #86):
|
||||
// D3D12 ERROR: ID3D12Device::GetResourceAllocationInfo: D3D12_RESOURCE_DESC::Flag D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT is not valid when the layout is either D3D12_TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE or D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE (...). [ STATE_CREATION ERROR #599: CREATERESOURCE_INVALIDMISCFLAGS]
|
||||
if((inOutResourceDesc.Flags & D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER) == 0
|
||||
&& (inOutResourceDesc.Layout != D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE && inOutResourceDesc.Layout != D3D12_TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE))
|
||||
{
|
||||
inOutResourceDesc.Flags |= D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT;
|
||||
}
|
||||
}
|
||||
#endif // #if D3D12MA_TIGHT_ALIGNMENT_SUPPORTED
|
||||
|
||||
/* Optional optimization: Microsoft documentation of the ID3D12Device::
|
||||
GetResourceAllocationInfo function says:
|
||||
|
||||
Your application can forgo using GetResourceAllocationInfo for buffer resources
|
||||
(D3D12_RESOURCE_DIMENSION_BUFFER). Buffers have the same size on all adapters,
|
||||
@@ -7767,20 +7838,25 @@ HRESULT AllocatorPimpl::GetResourceAllocationInfo(
|
||||
D3D12_RESOURCE_DESC::Width.
|
||||
*/
|
||||
if (inOutResourceDesc.Alignment == 0 &&
|
||||
inOutResourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
inOutResourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
|
||||
!IsTightAlignmentEnabled())
|
||||
{
|
||||
outAllocInfo = {
|
||||
AlignUp<UINT64>(inOutResourceDesc.Width, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT), // SizeInBytes
|
||||
D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT }; // Alignment
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#endif // #ifdef __ID3D12Device1_INTERFACE_DEFINED__
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
#if D3D12MA_USE_SMALL_RESOURCE_PLACEMENT_ALIGNMENT
|
||||
if (inOutResourceDesc.Alignment == 0 &&
|
||||
inOutResourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D &&
|
||||
(inOutResourceDesc.Flags & D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT_COPY) == 0 &&
|
||||
(inOutResourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D ||
|
||||
inOutResourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D ||
|
||||
inOutResourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) &&
|
||||
(inOutResourceDesc.Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)) == 0
|
||||
#if D3D12MA_USE_SMALL_RESOURCE_PLACEMENT_ALIGNMENT == 1
|
||||
&& CanUseSmallAlignment(inOutResourceDesc)
|
||||
@@ -8088,7 +8164,7 @@ BlockVector::BlockVector(
|
||||
m_MinBlockCount(minBlockCount),
|
||||
m_MaxBlockCount(maxBlockCount),
|
||||
m_ExplicitBlockSize(explicitBlockSize),
|
||||
m_MinAllocationAlignment(minAllocationAlignment),
|
||||
m_MinAllocationAlignment(D3D12MA_MAX(minAllocationAlignment, (UINT64)D3D12MA_DEBUG_ALIGNMENT)),
|
||||
m_Algorithm(algorithm),
|
||||
m_DenyMsaaTextures(denyMsaaTextures),
|
||||
m_ProtectedSession(pProtectedSession),
|
||||
@@ -9241,12 +9317,14 @@ PoolPimpl::PoolPimpl(AllocatorPimpl* allocator, const POOL_DESC& desc)
|
||||
D3D12MA_ASSERT(m_Desc.pProtectedSession == NULL);
|
||||
#endif
|
||||
|
||||
const UINT64 minAlignment = desc.MinAllocationAlignment > 0 ? desc.MinAllocationAlignment : D3D12MA_DEFAULT_ALIGNMENT;
|
||||
|
||||
m_BlockVector = D3D12MA_NEW(allocator->GetAllocs(), BlockVector)(
|
||||
allocator, desc.HeapProperties, desc.HeapFlags,
|
||||
preferredBlockSize,
|
||||
desc.MinBlockCount, maxBlockCount,
|
||||
explicitBlockSize,
|
||||
D3D12MA_MAX(desc.MinAllocationAlignment, (UINT64)D3D12MA_DEBUG_ALIGNMENT),
|
||||
minAlignment,
|
||||
(desc.Flags & POOL_FLAG_ALGORITHM_MASK) != 0,
|
||||
(desc.Flags & POOL_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED) != 0,
|
||||
desc.pProtectedSession,
|
||||
@@ -9709,6 +9787,11 @@ BOOL Allocator::IsGPUUploadHeapSupported() const
|
||||
return m_Pimpl->IsGPUUploadHeapSupported();
|
||||
}
|
||||
|
||||
BOOL Allocator::IsTightAlignmentSupported() const
|
||||
{
|
||||
return m_Pimpl->IsTightAlignmentSupported();
|
||||
}
|
||||
|
||||
UINT64 Allocator::GetMemoryCapacity(UINT memorySegmentGroup) const
|
||||
{
|
||||
return m_Pimpl->GetMemoryCapacity(memorySegmentGroup);
|
||||
@@ -9800,7 +9883,7 @@ HRESULT Allocator::AllocateMemory(
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
|
||||
return m_Pimpl->AllocateMemory(pAllocDesc, pAllocInfo, ppAllocation);
|
||||
return m_Pimpl->AllocateMemory(pAllocDesc, pAllocInfo, ppAllocation);
|
||||
}
|
||||
|
||||
HRESULT Allocator::CreateAliasingResource(
|
||||
|
||||
Vendored
+5
-5
@@ -4,8 +4,6 @@ add_library(demanglegnu STATIC
|
||||
src/cplus-dem.c
|
||||
src/d-demangle.c
|
||||
src/dyn-string.c
|
||||
src/getopt1.c
|
||||
src/getopt.c
|
||||
src/rust-demangle.c
|
||||
src/safe-ctype.c
|
||||
src/xexit.c
|
||||
@@ -19,9 +17,11 @@ set(GNU_DEMANGLER_FLAGS -DHAVE_DECL_BASENAME=1 -DHAVE_LIMITS_H=1 -DHAVE_STDLIB_H
|
||||
target_include_directories(demanglegnu PUBLIC include)
|
||||
target_compile_definitions(demanglegnu PUBLIC ${GNU_DEMANGLER_FLAGS})
|
||||
|
||||
add_executable(demangler_fuzzer testsuite/demangler-fuzzer.c)
|
||||
if((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME STREQUAL "Darwin"))
|
||||
add_executable(demangler_fuzzer testsuite/demangler-fuzzer.c)
|
||||
target_link_libraries(demangler_fuzzer demanglegnu)
|
||||
target_compile_definitions(demangler_fuzzer PUBLIC ${GNU_DEMANGLER_FLAGS})
|
||||
endif()
|
||||
add_executable(demangler_test testsuite/test-demangle.c)
|
||||
target_link_libraries(demangler_fuzzer demanglegnu)
|
||||
target_link_libraries(demangler_test demanglegnu)
|
||||
target_compile_definitions(demangler_fuzzer PUBLIC ${GNU_DEMANGLER_FLAGS})
|
||||
target_compile_definitions(demangler_test PUBLIC ${GNU_DEMANGLER_FLAGS})
|
||||
|
||||
-3
@@ -17,7 +17,6 @@ cp "$GCC_DIR/include/ansidecl.h" "$OUT_DIR/include/"
|
||||
cp "$GCC_DIR/include/demangle.h" "$OUT_DIR/include/"
|
||||
cp "$GCC_DIR/include/dyn-string.h" "$OUT_DIR/include/"
|
||||
cp "$GCC_DIR/include/environ.h" "$OUT_DIR/include/"
|
||||
cp "$GCC_DIR/include/getopt.h" "$OUT_DIR/include/"
|
||||
cp "$GCC_DIR/include/libiberty.h" "$OUT_DIR/include/"
|
||||
cp "$GCC_DIR/include/safe-ctype.h" "$OUT_DIR/include/"
|
||||
cp "$GCC_DIR/libiberty/alloca.c" "$OUT_DIR/src/"
|
||||
@@ -27,8 +26,6 @@ cp "$GCC_DIR/libiberty/cp-demangle.h" "$OUT_DIR/src/"
|
||||
cp "$GCC_DIR/libiberty/cplus-dem.c" "$OUT_DIR/src/"
|
||||
cp "$GCC_DIR/libiberty/d-demangle.c" "$OUT_DIR/src/"
|
||||
cp "$GCC_DIR/libiberty/dyn-string.c" "$OUT_DIR/src/"
|
||||
cp "$GCC_DIR/libiberty/getopt.c" "$OUT_DIR/src/"
|
||||
cp "$GCC_DIR/libiberty/getopt1.c" "$OUT_DIR/src/"
|
||||
cp "$GCC_DIR/libiberty/rust-demangle.c" "$OUT_DIR/src/"
|
||||
cp "$GCC_DIR/libiberty/safe-ctype.c" "$OUT_DIR/src/"
|
||||
cp "$GCC_DIR/libiberty/xexit.c" "$OUT_DIR/src/"
|
||||
|
||||
Vendored
-3
@@ -35,7 +35,6 @@
|
||||
<ClInclude Include="include\demangle.h" />
|
||||
<ClInclude Include="include\dyn-string.h" />
|
||||
<ClInclude Include="include\environ.h" />
|
||||
<ClInclude Include="include\getopt.h" />
|
||||
<ClInclude Include="include\libiberty.h" />
|
||||
<ClInclude Include="include\safe-ctype.h" />
|
||||
</ItemGroup>
|
||||
@@ -46,8 +45,6 @@
|
||||
<ClCompile Include="src\cplus-dem.c" />
|
||||
<ClCompile Include="src\d-demangle.c" />
|
||||
<ClCompile Include="src\dyn-string.c" />
|
||||
<ClCompile Include="src\getopt.c" />
|
||||
<ClCompile Include="src\getopt1.c" />
|
||||
<ClCompile Include="src\rust-demangle.c" />
|
||||
<ClCompile Include="src\safe-ctype.c" />
|
||||
<ClCompile Include="src\xexit.c" />
|
||||
|
||||
@@ -30,9 +30,6 @@
|
||||
<ClInclude Include="include\environ.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\getopt.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\libiberty.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -59,12 +56,6 @@
|
||||
<ClCompile Include="src\dyn-string.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\getopt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\getopt1.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\rust-demangle.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
||||
Vendored
-143
@@ -1,143 +0,0 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989-2023 Free Software Foundation, Inc.
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
||||
Bugs can be reported to bug-glibc@gnu.org.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
|
||||
USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
#define _GETOPT_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns -1, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int optopt;
|
||||
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct option
|
||||
{
|
||||
#if defined (__STDC__) && __STDC__
|
||||
const char *name;
|
||||
#else
|
||||
char *name;
|
||||
#endif
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
|
||||
#if defined (__STDC__) && __STDC__
|
||||
/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is
|
||||
undefined, we haven't run the autoconf check so provide the
|
||||
declaration without arguments. If it is 0, we checked and failed
|
||||
to find the declaration so provide a fully prototyped one. If it
|
||||
is 1, we found it so don't provide any declaration at all. */
|
||||
#if !HAVE_DECL_GETOPT
|
||||
#if defined (__GNU_LIBRARY__) || defined (HAVE_DECL_GETOPT)
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in unistd.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
extern int getopt (int argc, char *const *argv, const char *shortopts);
|
||||
#else
|
||||
#ifndef __cplusplus
|
||||
extern int getopt ();
|
||||
#endif /* __cplusplus */
|
||||
#endif
|
||||
#endif /* !HAVE_DECL_GETOPT */
|
||||
|
||||
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
extern int getopt_long_only (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
|
||||
/* Internal only. Users should not call this directly. */
|
||||
extern int _getopt_internal (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind,
|
||||
int long_only);
|
||||
#else /* not __STDC__ */
|
||||
extern int getopt ();
|
||||
extern int getopt_long ();
|
||||
extern int getopt_long_only ();
|
||||
|
||||
extern int _getopt_internal ();
|
||||
#endif /* __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* getopt.h */
|
||||
Vendored
-1051
File diff suppressed because it is too large
Load Diff
Vendored
-179
@@ -1,179 +0,0 @@
|
||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
|
||||
NOTE: This source is derived from an old version taken from the GNU C
|
||||
Library (glibc).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
|
||||
USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if !defined __STDC__ || !__STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#define GETOPT_INTERFACE_VERSION 2
|
||||
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
|
||||
#include <gnu-versions.h>
|
||||
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
|
||||
#define ELIDE_CODE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ELIDE_CODE
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int
|
||||
getopt_long (int argc, char *const *argv, const char *options,
|
||||
const struct option *long_options, int *opt_index)
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
getopt_long_only (int argc, char *const *argv, const char *options,
|
||||
const struct option *long_options, int *opt_index)
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
|
||||
#endif /* Not ELIDE_CODE. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
int option_index = 0;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"add", 1, 0, 0},
|
||||
{"append", 0, 0, 0},
|
||||
{"delete", 1, 0, 0},
|
||||
{"verbose", 0, 0, 0},
|
||||
{"create", 0, 0, 0},
|
||||
{"file", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "abc:d:0123456789",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
printf ("option d with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
Vendored
+8
-27
@@ -1,38 +1,19 @@
|
||||
# We need to use a custom CMakeLists for GoogleTest, because we can't compile with exceptions on.
|
||||
|
||||
add_library(gtest
|
||||
googletest/src/gtest.cc
|
||||
googletest/src/gtest-assertion-result.cc
|
||||
googletest/src/gtest-death-test.cc
|
||||
googletest/src/gtest-filepath.cc
|
||||
googletest/src/gtest-matchers.cc
|
||||
googletest/src/gtest-port.cc
|
||||
googletest/src/gtest-printers.cc
|
||||
googletest/src/gtest-test-part.cc
|
||||
googletest/src/gtest-typed-test.cc
|
||||
googletest/src/gtest-all.cc
|
||||
googlemock/src/gmock-all.cc
|
||||
googlemock/src/gmock_main.cc
|
||||
)
|
||||
target_include_directories(gtest PUBLIC
|
||||
googletest/include
|
||||
googlemock/include
|
||||
)
|
||||
target_include_directories(gtest PRIVATE
|
||||
googletest
|
||||
googletest/include
|
||||
)
|
||||
target_include_directories(gtest INTERFACE
|
||||
googletest/include
|
||||
googlemock
|
||||
)
|
||||
target_link_libraries(gtest Threads::Threads)
|
||||
set_property(TARGET gtest PROPERTY CXX_STANDARD 17)
|
||||
set_property(TARGET gtest PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
add_library(gtest_main
|
||||
googletest/src/gtest_main.cc
|
||||
)
|
||||
target_include_directories(gtest_main PRIVATE
|
||||
googletest
|
||||
googletest/include
|
||||
)
|
||||
target_include_directories(gtest_main INTERFACE
|
||||
googletest/include
|
||||
)
|
||||
target_link_libraries(gtest_main Threads::Threads)
|
||||
set_property(TARGET gtest_main PROPERTY CXX_STANDARD 17)
|
||||
set_property(TARGET gtest_main PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
|
||||
Vendored
+251
-2
@@ -1,6 +1,10 @@
|
||||
dear imgui
|
||||
CHANGELOG
|
||||
|
||||
PCSX2 Changes (must be reapplied after each update, use git blame on this changelog to inspect the commit that originally applied the change):
|
||||
- Don't shrink fonts based on their line height, and allow PCSX2 to specify a line height
|
||||
- Issue: https://github.com/ocornut/imgui/issues/9063
|
||||
|
||||
This document holds the user-facing changelog that we also use in release notes.
|
||||
We generally fold multiple commits pertaining to the same topic as a single entry.
|
||||
Changes to backends are also included within the individual .cpp files of each backend.
|
||||
@@ -35,6 +39,248 @@ HOW TO UPDATE?
|
||||
and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users.
|
||||
- Please report any issue!
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.92.6 (2026-02-17)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.92.6
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- Fonts:
|
||||
- `AddFontDefault()` now automatically selects an embedded font between:
|
||||
- `AddFontDefaultBitmap()`: classic pixel-clean font. Recommended at Size 13px with no scaling.
|
||||
- `AddFontDefaultVector()`: new scalable font. Recommended at any higher size.
|
||||
- The default selection is based on (style.FontSizeBase * FontScaleMain * FontScaleDpi)
|
||||
reaching a small threshold, but old codebases may not set any of them properly.
|
||||
As as a result, it is likely that old codebase may still default to AddFontDefaultBitmap().
|
||||
- Prefer explicitly calling either of them based on your own logic!
|
||||
You can call `AddFontDefaultBitmap()` to ensure legacy behavior.
|
||||
- Fixed handling of `ImFontConfig::FontDataOwnedByAtlas = false` which did
|
||||
erroneously make a copy of the font data, essentially defeating the purpose
|
||||
of this flag and wasting memory (undetected since July 2015 and now spotted
|
||||
by @TellowKrinkle, this is perhaps the oldest bug in Dear ImGui history,
|
||||
albeit for a rarely used feature!) (#9086, #8465)
|
||||
HOWEVER, fixing this bug is likely to surface bugs in user/app code:
|
||||
- Prior to 1.92, font data only needs to be available during the `atlas->AddFontXXX()` call.
|
||||
Since 1.92, font data needs to available until `atlas->RemoveFont()`, or more typically
|
||||
until a shutdown of the owning context or font atlas.
|
||||
- The fact that handling of `FontDataOwnedByAtlas = false` was broken bypassed
|
||||
the issue altogether.
|
||||
- Removed `ImFontConfig::PixelSnapV` added in 1.92 which turns out is unnecessary
|
||||
(and was mis-documented). Post-rescale `GlyphOffset` is always rounded.
|
||||
- Popups: changed compile-time `ImGuiPopupFlags popup_flags = 1` default value to be `= 0` for
|
||||
`BeginPopupContextItem()`, `BeginPopupContextWindow()`, `BeginPopupContextVoid()`, `OpenPopupOnItemClick()`.
|
||||
The default value has same meaning before and after. (#9157, #9146)
|
||||
- Before this version, those functions had a `ImGuiPopupFlags popup_flags = 1` default
|
||||
value in their function signature. This was introduced by a change on 2020/06/23 (1.77)
|
||||
while changing the signature from `int mouse_button` to `ImGuiPopupFlags popup_flags`
|
||||
and trying to preserve then-legacy behavior.
|
||||
- We have now changed this behavior to: cleanup a very old API quirk, facilitate use by
|
||||
bindings, and to remove the last and error-prone non-zero default value. Also because we
|
||||
deemed it extremely rare to use those helper functions with the Left mouse button!
|
||||
As using the LMB would generally be triggered via another widget,
|
||||
e.g. a Button() + a OpenPopup()/BeginPopup() call.
|
||||
- Before: The default = 1 means `ImGuiPopupFlags_MouseButtonRight`.
|
||||
Explicitly passing a literal 0 means `ImGuiPopupFlags_MouseButtonLeft`.
|
||||
- After: The default = 0 means `ImGuiPopupFlags_MouseButtonRight`.
|
||||
Explicitly passing a literal 1 also means `ImGuiPopupFlags_MouseButtonRight`.
|
||||
(if legacy behavior are enabled) or will assert (if legacy behavior are disabled).
|
||||
- TL;DR: if you don't want to use right mouse button for popups, always specify it
|
||||
explicitly using a named `ImGuiPopupFlags_MouseButtonXXXX` value.
|
||||
Recap:
|
||||
- BeginPopupContextItem("foo"); // Behavior unchanged (use Right button)
|
||||
- BeginPopupContextItem("foo", ImGuiPopupFlags_MouseButtonLeft); // Behavior unchanged (use Left button)
|
||||
- BeginPopupContextItem("foo", ImGuiPopupFlags_MouseButtonLeft | xxx); // Behavior unchanged (use Left button + flags)
|
||||
- BeginPopupContextItem("foo", ImGuiPopupFlags_MouseButtonRight | xxx); // Behavior unchanged (use Right button + flags)
|
||||
- BeginPopupContextItem("foo", 1); // Behavior unchanged (as a courtesy we legacy interpret 1 as ImGuiPopupFlags_MouseButtonRight, will assert if disabling legacy behaviors.
|
||||
- BeginPopupContextItem("foo", 0); // !! Behavior changed !! Was Left button. Now will defaults to Right button! --> Use ImGuiPopupFlags_MouseButtonLeft.
|
||||
- BeginPopupContextItem("foo", ImGuiPopupFlags_NoReopen); // !! Behavior changed !! Was Left button + flags. Now will defaults to Right button! --> Use ImGuiPopupFlags_MouseButtonLeft | xxx.
|
||||
- Commented out legacy names obsoleted in 1.90 (Sept 2023):
|
||||
- `BeginChildFrame()` --> `BeginChild()` with `ImGuiChildFlags_FrameStyle` flag.
|
||||
- `EndChildFrame()` --> `EndChild()`.
|
||||
- `ShowStackToolWindow()` --> `ShowIDStackToolWindow()`.
|
||||
- `IM_OFFSETOF()` --> `offsetof()`.
|
||||
- `IM_FLOOR()` --> `IM_TRUNC()` [internal, for positive values only]
|
||||
- Hashing: handling of "###" operator to reset to seed within a string identifier
|
||||
doesn't include the "###" characters in the output hash anymore:
|
||||
Before: `GetID("Hello###World") == GetID("###World") != GetID("World")`
|
||||
After: `GetID("Hello###World") == GetID("###World") == GetID("World")`
|
||||
- This has the property of facilitating concatenating and manipulating
|
||||
identifiers using "###", and will allow fixing other dangling issues.
|
||||
- This will invalidate hashes (stored in .ini data) for Tables and Windows
|
||||
that are using the "###" operators. (#713, #1698)
|
||||
- Renamed helper macro `IM_ARRAYSIZE()` -> `IM_COUNTOF()`. Kept redirection/legacy name.
|
||||
- Backends:
|
||||
- Vulkan: optional `ImGui_ImplVulkanH_DestroyWindow()` helper used by our example
|
||||
code does not call `vkDestroySurfaceKHR()`: because surface is created by caller
|
||||
of `ImGui_ImplVulkanH_CreateOrResizeWindow()`, it is more consistent. (#9163)
|
||||
|
||||
Other Changes:
|
||||
|
||||
- Fonts:
|
||||
- Added `AddFontDefaultVector()`: a new embedded monospace scalable font: ProggyForever!
|
||||
From https://github.com/ocornut/proggyforever:
|
||||
"ProggyForever is an MIT-licensed partial reimplementation of the ProggyVector
|
||||
font (originally by Tristan Grimmer), which itself is a vector-based
|
||||
reinterpretation of the ProggyClean bitmap font that happily served as
|
||||
Dear ImGui default font for over 10 years." [...]
|
||||
"I commissioned Thiebault Courot to recreate this, applied various minor tweaks
|
||||
and fixes, and reworked his editing pipeline toward shipping FontForge source
|
||||
files so we can allow and track future changes."
|
||||
- TL;DR; there was no strictly MIT-licensed matching font. We made it!
|
||||
- The font data was carefully subsetted, trimmed and compressed so the embedded
|
||||
data is ~14 KB. Embedding a scalable default font ensures that Dear ImGui can
|
||||
be easily and readily used in all contexts, even without file system access.
|
||||
- Expect minor fixes/improvements in following releases.
|
||||
- As always you can opt-out of the embedded font data if desired.
|
||||
- `AddFontDefault()` now automatically selects an embedded font between
|
||||
the classic pixel-looking one and the new scalable one.
|
||||
Prefer calling `AddFontDefaultVector()` or `AddFontDefaultBitmap()` explicitly.
|
||||
- Fixed a crash when trying to use `AddFont()` with `MergeMode==true` on a font that
|
||||
has already been rendered. (#9162) [@ocornut, @cyfewlp]
|
||||
- Fixed an issue where using `PushFont()` from the implicit/fallback "Debug" window
|
||||
when its recorded state is collapsed would incorrectly early out. This would break
|
||||
e.g. using direct draw-list calls such as `GetForegroundDrawList()` with current font.
|
||||
(#9210, #8865)
|
||||
- Fixed an issue related to `EllipsisChar` handling, while changing
|
||||
font loader or font loader flags dynamically in Style->Fonts menus.
|
||||
- imgui_freetype: fixed overwriting `ImFontConfig::PixelSnapH` when hinting
|
||||
is enabled, creating side-effects when later disabling hinting or
|
||||
dynamically switching to stb_truetype rasterizer.
|
||||
- Adding new fonts after removing all fonts mid-frame properly updates current state.
|
||||
- Textures:
|
||||
- Fixed a building issue when `ImTextureID` is defined as a struct.
|
||||
- Fixed displaying texture # in Metrics/Debugger window.
|
||||
- Menus:
|
||||
- Fixed `MenuItem()` label position and `BeginMenu()` arrow/icon/popup positions,
|
||||
when used inside a line with a baseline offset.
|
||||
- Made navigation into menu-bar auto wrap on X axis. (#9178)
|
||||
- TreeNode:
|
||||
- Fixed highlight position when used inside a line with a large text baseline offset.
|
||||
(it never quite worked in this situation; but then most of the time the text
|
||||
baseline offset ends up being zero or `FramePadding.y` for a given line).
|
||||
- Tables:
|
||||
- Fixed an issue where a very thin scrolling table would advance parent layout
|
||||
slightly differently depending on its visibility (caused by a mismatch
|
||||
between hard minimum window size and table minimum size).
|
||||
- Fixed an issue where submitting non-integer row heights would eventually
|
||||
advance table parent layout by +0/+1 depending on its visibility.
|
||||
- Fixed losing stored display order when reducing column count or when .ini
|
||||
data has missing or duplicate values. (#9108, #4046)
|
||||
- ColorEdit:
|
||||
- Added R/G/B/A color markers next to each component (enabled by default).
|
||||
- Added `ImGuiColorEditFlags_NoColorMarkers` to disable them.
|
||||
- Added `style.ColorMarkerSize` to configure width of color component markers.
|
||||
- Sliders, Drags:
|
||||
- Added `ImGuiSliderFlags_ColorMarkers` to opt-in adding R/G/B/A color markers
|
||||
next to each components, in multi-components functions.
|
||||
- Added a way to select a specific marker color.
|
||||
- InputText:
|
||||
- InputTextMultiline(): fixed a minor bug where Shift+Wheel would allow a small
|
||||
horizontal scroll offset when there should be none. (#9249)
|
||||
- ImGuiInputTextCallbackData: `SelectAll()` also sets `CursorPos` to `SelectionEnd`.
|
||||
- ImGuiInputTextCallbackData: Added `SetSelection()` helper.
|
||||
- ImGuiInputTextCallbackData: Added `ID` and `EventActivated` members. (#9174)
|
||||
- Text, InputText:
|
||||
- Reworked word-wrapping logic:
|
||||
- Try to not wrap in the middle of contiguous punctuation. (#8139, #8439, #9094)
|
||||
- Try to not wrap between a punctuation and a digit. (#8503)
|
||||
- Inside `InputTextMultiline()` with WordWrap enabled: prefer keeping blanks at
|
||||
the end of a line rather than at the beginning of next line. (#8990, #3237)
|
||||
- Fixed low-level word-wrapping function reading from `*text_end` when passed
|
||||
a string range. (#9107) [@achabense]
|
||||
- Changed `RenderTextEllipsis()` logic to not trim trailing blanks before
|
||||
the ellipsis, making ellipsis position more consistent and not arbitrary
|
||||
hiding the possibility of multiple blanks. (#9229)
|
||||
- Nav:
|
||||
- Fixed remote/shortcut InputText() not teleporting mouse cursor when
|
||||
nav cursor is visible and `io.ConfigNavMoveSetMousePos` is enabled.
|
||||
- Fixed a looping/wrapping issue when used in menu layer. (#9178)
|
||||
- Fixed speed scale for resizing/moving with keyboard/gamepad. We incorrectly
|
||||
used `io.DisplayFramebufferScale` as a scaling factor (very old code),
|
||||
effectively making those actions faster on macOS/iOS retina screens.
|
||||
(changed this to use a style scale factor that's not fully formalized yet)
|
||||
- Fixed an UBSan warning when using in a `ImGuiListClipper` region . (#9160)
|
||||
- Scrollbar: fixed a code-path leading to a divide-by-zero (which would not be
|
||||
noticeable by user but detected by sanitizers). (#9089) [@judicaelclair]
|
||||
- InvisibleButton: allow calling with size (0,0) to fit to available content
|
||||
size. (#9166, #7623)
|
||||
- Tooltips, Disabled: fixed `EndDisabledOverrideReenable()` assertion when
|
||||
nesting a tooltip in a disabled block. (#9180, #7640) [@RegimantasSimkus]
|
||||
- Added `GetItemFlags()` in public API for consistency and to expose generic
|
||||
flags of last submitted item. (#9127)
|
||||
- Misc: fixed build on ARM64/ARM64EC targets trying to use SSE/immintrin.h.
|
||||
(#9209, #5943, #4091) [@navvyswethgraphics]
|
||||
- Log/Capture:
|
||||
- Fixed erroneously injecting extra carriage returns in output text buffer
|
||||
when `ItemSpacing.y` > `FramePadding.y + 1` while emitting items.
|
||||
- Images:
|
||||
- Added `style.ImageRounding`, `ImGuiStyleVar_ImageRounding `to configure
|
||||
rounding of `Image()` widgets. (#2942, #845)
|
||||
- `ImageButton()` doesn't use a clamped `style.FrameRounding` value but instead
|
||||
adjust inner image rounding when `FramePadding > `FrameRounding`. (#2942, #845)
|
||||
- Shortcuts:
|
||||
- IsItemHovered() without `ImGuiHoveredFlags_AllowWhenBlockedByActiveItem`
|
||||
doesn't filter out the signal when activated item is a shortcut remote activation;
|
||||
(which mimics what's done internally in the `ItemHoverable()` function). (#9138)
|
||||
- Fixed tooltip placement being affected for a frame when located over an item
|
||||
activated by `SetNextItemShortcut()`. (#9138)
|
||||
- Error Handling:
|
||||
- Improved error handling and recovery for `EndMenu()`/`EndCombo()`. (#1651, #9165, #8499)
|
||||
- Improved error handling and recovery for `TableSetupColumn()`.
|
||||
- Debug Tools:
|
||||
- Debug Log: fixed incorrectly printing characters in IO log when submitting
|
||||
non-ASCII values to `io.AddInputCharacter()`. (#9099)
|
||||
- Debug Log: can output to debugger on Windows via Win32 `OutputDebugString()` (#5855)
|
||||
- Demo:
|
||||
- Slightly improve `Selectable()` demos. (#9193)
|
||||
- Backends:
|
||||
- DirectX10: added `SamplerNearest` in `ImGui_ImplDX10_RenderState`.
|
||||
(+renamed `SamplerDefault` to `SamplerLinear`, which was tagged as beta API)
|
||||
- DirectX11: added `SamplerNearest` in ImGui_ImplDX11_RenderState.
|
||||
(+renamed `SamplerDefault` to `SamplerLinear`, which was tagged as beta API)
|
||||
- GLFW: Avoid repeated `glfwSetCursor()` / `glfwSetInputMode()` unnecessary calls.
|
||||
Lowers overhead for very high framerates (e.g. 10k+ FPS). [@maxliani]
|
||||
- GLFW: Added `IMGUI_IMPL_GLFW_DISABLE_X11` / `IMGUI_IMPL_GLFW_DISABLE_WAYLAND` to
|
||||
forcefully disable either. (#9109, #9116)
|
||||
Try to set them automatically if headers are not accessible. (#9225)
|
||||
- OpenGL3: Fixed embedded loader multiple init/shutdown cycles broken on some
|
||||
platforms. (#8792, #9112)
|
||||
- SDL2, SDL3: changed `GetClipboardText()` handler to return NULL on error aka
|
||||
clipboard contents is not text. Consistent with other backends. (#9168)
|
||||
- SDL2, SDL3: systems other than X11 are back to starting mouse capture on mouse down
|
||||
(reverts 1.91.9 change). Only X11 requires waiting for a drag by default (not ideal,
|
||||
but a better default for X11 users). Waiting for a drag to start mouse capture leads to
|
||||
input drops when dragging after clicking on the edge of a window.
|
||||
(#3650, #6410, #9235, #3956, #3835)
|
||||
- SDL2, SDL3: added `ImGui_ImplSDL2_SetMouseCaptureMode()`/`ImGui_ImplSDL3_SetMouseCaptureMode()`
|
||||
function for X11 users to disable mouse capturing/grabbing. (#3650, #6410, #9235, #3956, #3835)
|
||||
- When attached to a debugger may want to call:
|
||||
- `ImGui_ImplSDL3_SetMouseCaptureMode(ImGui_ImplSDL3_MouseCaptureMode_Disabled);`
|
||||
- But you can also configure your system or debugger to automatically release
|
||||
mouse grab when crashing/breaking in debugger, e.g.
|
||||
- console: `setxkbmap -option grab:break_actions && xdotool key XF86Ungrab`
|
||||
- or use a GDB script to call `SDL_CaptureMouse(false)`. See #3650.
|
||||
- On platforms other than X11 this is unnecessary.
|
||||
- SDL_GPU3: added `SamplerNearest` in `ImGui_ImplSDLGPU3_RenderState`.
|
||||
- SDL_GPU3: macOS version can use MSL shaders in order to support macOS 10.14+
|
||||
(vs Metallib shaders requiring macOS 14+). Requires application calling
|
||||
`SDL_CreateGPUDevice()` with `SDL_GPU_SHADERFORMAT_MSL`. (#9076) [@Niminem]
|
||||
- Vulkan: helper for creating a swapchain (used by examples and multi-viewports)
|
||||
selects `VkSwapchainCreateInfoKHR`'s `compositeAlpha` value based on
|
||||
`cap.supportedCompositeAlpha`, which seems to be required on some Android
|
||||
devices. (#8784) [@FelixStach]
|
||||
- WebGPU: fixes for Emscripten 5.0.0 (note: current examples do not build with 5.0.1).
|
||||
- Win32: handle `WM_IME_CHAR`/`WM_IME_COMPOSITION` to support Unicode inputs on
|
||||
MBCS (non-Unicode) Windows. (#9099, #3653, #5961) [@ulhc, @ocornut, @Othereum]
|
||||
- Win32: minor optimization not submitting gamepad input if packet number has not
|
||||
changed (reworked previous 1.92.4). (#9202, #8556) [@AhmedSamyMousa, @MidTerm-CN]
|
||||
- Examples:
|
||||
- Win32+DirectX12: ignore seemingly incorrect `D3D12_MESSAGE_ID_FENCE_ZERO_WAIT`
|
||||
warning on startups on some setups. (#9084, #9093) [@RT2Code, @LeoGautheron]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.92.5 (Released 2025-11-20)
|
||||
-----------------------------------------------------------------------
|
||||
@@ -141,7 +387,7 @@ Other Changes:
|
||||
debug/metrics window is not in the same viewport as the table.
|
||||
- Backends:
|
||||
- NULL: added imgui_impl_null platform/renderer backend.
|
||||
This is designed if you need to run e.g. context with no input or no ouput.
|
||||
This is designed if you need to run e.g. context with no input or no output.
|
||||
- GLFW: fixed building on Linux platforms where Wayland headers
|
||||
are not available. (#9024, #8969, #8921, #8920) [@jagot]
|
||||
- GLFW: lower minimum requirement from GLFW 3.1 to GLFW 3.0. Though
|
||||
@@ -219,6 +465,8 @@ Other Changes:
|
||||
using ImGuiWindowFlags_UnsavedDocument/ImGuiTabItemFlags_UnsavedDocument. (#8983)
|
||||
- IO: added ImGuiPlatformIO::ClearPlatformHandlers(), ClearRendererHandlers()
|
||||
helpers to null all handlers. (#8945, #2769)
|
||||
- Tables: changed ImGuiTableFlags_NoBordersInBody behavior to not draw border in
|
||||
body even when resizing. (#8893)
|
||||
- Inputs:
|
||||
- Shortcuts: added support for combining ImGuiInputFlags_RouteFocused
|
||||
(which is the default route) with ImGuiInputFlags_RouteOverActive, allowing
|
||||
@@ -621,7 +869,7 @@ Breaking changes:
|
||||
which font input is providing which glyph.
|
||||
- Fonts: **IMPORTANT** on Thread Safety:
|
||||
- A few functions such as font->CalcTextSizeA() were by sheer luck (== accidentally)
|
||||
thread-safe even thou we had never provided that guarantee before. They are
|
||||
thread-safe even though we had never provided that guarantee before. They are
|
||||
definitively not thread-safe anymore as new glyphs may be loaded.
|
||||
|
||||
- Textures:
|
||||
@@ -1374,6 +1622,7 @@ Breaking changes:
|
||||
- Commented out pre-1.87 IO system (equivalent to using IMGUI_DISABLE_OBSOLETE_KEYIO or IMGUI_DISABLE_OBSOLETE_FUNCTIONS before).
|
||||
- io.KeyMap[] and io.KeysDown[] are removed (obsoleted February 2022). Use IsKeyDown() instead.
|
||||
- io.NavInputs[] and ImGuiNavInput are removed (obsoleted July 2022).
|
||||
- GetKeyIndex() is removed (obsoleted March 2022). The indirection is now unnecessary.
|
||||
- Pre-1.87 backends are not supported:
|
||||
- backends need to call io.AddKeyEvent(), io.AddMouseEvent() instead of writing to io.KeysDown[], io.MouseDown[] fields.
|
||||
- backends need to call io.AddKeyAnalogEvent() for gamepad values instead of writing to io.NavInputs[] fields.
|
||||
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2026 Omar Cornut
|
||||
|
||||
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.
|
||||
Vendored
+1
-1
@@ -49,7 +49,7 @@
|
||||
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded font (ProggyClean.ttf), remove ~9.5 KB from output binary. AddFontDefault() will assert.
|
||||
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded fonts (ProggyClean/ProggyForever), remove ~9 KB + ~14 KB from output binary. AddFontDefaultXXX() functions will assert.
|
||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||
|
||||
//---- Enable Test Engine / Automation features.
|
||||
|
||||
Vendored
+106
-79
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.5
|
||||
// dear imgui, v1.92.6
|
||||
// (headers)
|
||||
|
||||
// Help:
|
||||
@@ -29,8 +29,8 @@
|
||||
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.92.5"
|
||||
#define IMGUI_VERSION_NUM 19250
|
||||
#define IMGUI_VERSION "1.92.6"
|
||||
#define IMGUI_VERSION_NUM 19261
|
||||
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
|
||||
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
|
||||
|
||||
@@ -95,7 +95,7 @@ Index of this file:
|
||||
#include <assert.h>
|
||||
#define IM_ASSERT(_EXPR) assert(_EXPR) // You can override the default assert handler by editing imconfig.h
|
||||
#endif
|
||||
#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers!
|
||||
#define IM_COUNTOF(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers!
|
||||
#define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds.
|
||||
#define IM_STRINGIFY_HELPER(_EXPR) #_EXPR
|
||||
#define IM_STRINGIFY(_EXPR) IM_STRINGIFY_HELPER(_EXPR) // Preprocessor idiom to stringify e.g. an integer or a macro.
|
||||
@@ -349,7 +349,7 @@ typedef ImU64 ImTextureID; // Default: store up to 64-bits (any pointer or
|
||||
// The identifier is valid even before the texture has been uploaded to the GPU/graphics system.
|
||||
// This is what gets passed to functions such as `ImGui::Image()`, `ImDrawList::AddImage()`.
|
||||
// This is what gets stored in draw commands (`ImDrawCmd`) to identify a texture during rendering.
|
||||
// - When a texture is created by user code (e.g. custom images), we directly stores the low-level ImTextureID.
|
||||
// - When a texture is created by user code (e.g. custom images), we directly store the low-level ImTextureID.
|
||||
// Because of this, when displaying your own texture you are likely to ever only manage ImTextureID values on your side.
|
||||
// - When a texture is created by the backend, we stores a ImTextureData* which becomes an indirection
|
||||
// to extract the ImTextureID value during rendering, after texture upload has happened.
|
||||
@@ -853,20 +853,23 @@ namespace ImGui
|
||||
// - CloseCurrentPopup() is called by default by Selectable()/MenuItem() when activated (FIXME: need some options).
|
||||
// - Use ImGuiPopupFlags_NoOpenOverExistingPopup to avoid opening a popup if there's already one at the same level. This is equivalent to e.g. testing for !IsAnyPopupOpen() prior to OpenPopup().
|
||||
// - Use IsWindowAppearing() after BeginPopup() to tell if a window just opened.
|
||||
// - IMPORTANT: Notice that for OpenPopupOnItemClick() we exceptionally default flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter
|
||||
IMGUI_API void OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags = 0); // call to mark popup as open (don't call every frame!).
|
||||
IMGUI_API void OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags = 0); // id overload to facilitate calling from nested stacks
|
||||
IMGUI_API void OpenPopupOnItemClick(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // helper to open popup when clicked on last item. Default to ImGuiPopupFlags_MouseButtonRight == 1. (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors)
|
||||
IMGUI_API void OpenPopupOnItemClick(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 0); // helper to open popup when clicked on last item. Default to ImGuiPopupFlags_MouseButtonRight == 1. (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors)
|
||||
IMGUI_API void CloseCurrentPopup(); // manually close the popup we have begin-ed into.
|
||||
|
||||
// Popups: open+begin combined functions helpers
|
||||
// Popups: Open+Begin popup combined functions helpers to create context menus.
|
||||
// - Helpers to do OpenPopup+BeginPopup where the Open action is triggered by e.g. hovering an item and right-clicking.
|
||||
// - They are convenient to easily create context menus, hence the name.
|
||||
// - IMPORTANT: Notice that BeginPopupContextXXX takes ImGuiPopupFlags just like OpenPopup() and unlike BeginPopup(). For full consistency, we may add ImGuiWindowFlags to the BeginPopupContextXXX functions in the future.
|
||||
// - IMPORTANT: Notice that we exceptionally default their flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter, so if you add other flags remember to re-add the ImGuiPopupFlags_MouseButtonRight.
|
||||
IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked on last item. Use str_id==NULL to associate the popup to previous item. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp!
|
||||
IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1);// open+begin popup when clicked on current window.
|
||||
IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked in void (where there are no windows).
|
||||
// - IMPORTANT: If you ever used the left mouse button with BeginPopupContextXXX() helpers before 1.92.6:
|
||||
// - Before this version, OpenPopupOnItemClick(), BeginPopupContextItem(), BeginPopupContextWindow(), BeginPopupContextVoid() had 'a ImGuiPopupFlags popup_flags = 1' default value in their function signature.
|
||||
// - Before: Explicitly passing a literal 0 meant ImGuiPopupFlags_MouseButtonLeft. The default = 1 meant ImGuiPopupFlags_MouseButtonRight.
|
||||
// - After: The default = 0 means ImGuiPopupFlags_MouseButtonRight. Explicitly passing a literal 1 also means ImGuiPopupFlags_MouseButtonRight (if legacy behavior are enabled) or will assert (if legacy behavior are disabled).
|
||||
// - TL;DR: if you don't want to use right mouse button for popups, always specify it explicitly using a named ImGuiPopupFlags_MouseButtonXXXX value.
|
||||
// - Read "API BREAKING CHANGES" 2026/01/07 (1.92.6) entry in imgui.cpp or GitHub topic #9157 for all details.
|
||||
IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 0); // open+begin popup when clicked on last item. Use str_id==NULL to associate the popup to previous item. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp!
|
||||
IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 0);// open+begin popup when clicked on current window.
|
||||
IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 0); // open+begin popup when clicked in void (where there are no windows).
|
||||
|
||||
// Popups: query functions
|
||||
// - IsPopupOpen(): return true if the popup is open at the current BeginPopup() level of the popup stack.
|
||||
@@ -897,7 +900,7 @@ namespace ImGui
|
||||
// - 5. Call EndTable()
|
||||
IMGUI_API bool BeginTable(const char* str_id, int columns, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0.0f, 0.0f), float inner_width = 0.0f);
|
||||
IMGUI_API void EndTable(); // only call EndTable() if BeginTable() returns true!
|
||||
IMGUI_API void TableNextRow(ImGuiTableRowFlags row_flags = 0, float min_row_height = 0.0f); // append into the first cell of a new row.
|
||||
IMGUI_API void TableNextRow(ImGuiTableRowFlags row_flags = 0, float min_row_height = 0.0f); // append into the first cell of a new row. 'min_row_height' include the minimum top and bottom padding aka CellPadding.y * 2.0f.
|
||||
IMGUI_API bool TableNextColumn(); // append into the next column (or first column of next row if currently in last column). Return true when column is visible.
|
||||
IMGUI_API bool TableSetColumnIndex(int column_n); // append into the specified column. Return true when column is visible.
|
||||
|
||||
@@ -977,7 +980,7 @@ namespace ImGui
|
||||
// Disabling [BETA API]
|
||||
// - Disable all user interactions and dim items visuals (applying style.DisabledAlpha over current colors)
|
||||
// - Those can be nested but it cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep everything disabled)
|
||||
// - Tooltips windows are automatically opted out of disabling. Note that IsItemHovered() by default returns false on disabled items, unless using ImGuiHoveredFlags_AllowWhenDisabled.
|
||||
// - Tooltips windows are automatically opted out of disabling. Note that IsItemHovered() by default returns false on disabled items, unless using ImGuiHoveredFlags_AllowWhenDisabled.
|
||||
// - BeginDisabled(false)/EndDisabled() essentially does nothing but is provided to facilitate use of boolean expressions (as a micro-optimization: if you have tens of thousands of BeginDisabled(false)/EndDisabled() pairs, you might want to reformulate your code to avoid making those calls)
|
||||
IMGUI_API void BeginDisabled(bool disabled = true);
|
||||
IMGUI_API void EndDisabled();
|
||||
@@ -1017,6 +1020,7 @@ namespace ImGui
|
||||
IMGUI_API ImVec2 GetItemRectMin(); // get upper-left bounding rectangle of the last item (screen space)
|
||||
IMGUI_API ImVec2 GetItemRectMax(); // get lower-right bounding rectangle of the last item (screen space)
|
||||
IMGUI_API ImVec2 GetItemRectSize(); // get size of last item
|
||||
IMGUI_API ImGuiItemFlags GetItemFlags(); // get generic flags of last item
|
||||
|
||||
// Viewports
|
||||
// - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows.
|
||||
@@ -1047,19 +1051,22 @@ namespace ImGui
|
||||
IMGUI_API void ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v);
|
||||
IMGUI_API void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b);
|
||||
|
||||
// Inputs Utilities: Keyboard/Mouse/Gamepad
|
||||
// Inputs Utilities: Raw Keyboard/Mouse/Gamepad Access
|
||||
// - Consider using the Shortcut() function instead of IsKeyPressed()/IsKeyChordPressed()! Shortcut() is easier to use and better featured (can do focus routing check).
|
||||
// - the ImGuiKey enum contains all possible keyboard, mouse and gamepad inputs (e.g. ImGuiKey_A, ImGuiKey_MouseLeft, ImGuiKey_GamepadDpadUp...).
|
||||
// - (legacy: before v1.87, we used ImGuiKey to carry native/user indices as defined by each backends. This was obsoleted in 1.87 (2022-02) and completely removed in 1.91.5 (2024-11). See https://github.com/ocornut/imgui/issues/4921)
|
||||
// - (legacy: any use of ImGuiKey will assert when key < 512 to detect passing legacy native/user indices)
|
||||
// - (legacy: before v1.87 (2022-02), we used ImGuiKey < 512 values to carry native/user indices as defined by each backends. This was obsoleted in 1.87 (2022-02) and completely removed in 1.91.5 (2024-11). See https://github.com/ocornut/imgui/issues/4921)
|
||||
IMGUI_API bool IsKeyDown(ImGuiKey key); // is key being held.
|
||||
IMGUI_API bool IsKeyPressed(ImGuiKey key, bool repeat = true); // was key pressed (went from !Down to Down)? if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate
|
||||
IMGUI_API bool IsKeyPressed(ImGuiKey key, bool repeat = true); // was key pressed (went from !Down to Down)? Repeat rate uses io.KeyRepeatDelay / KeyRepeatRate.
|
||||
IMGUI_API bool IsKeyReleased(ImGuiKey key); // was key released (went from Down to !Down)?
|
||||
IMGUI_API bool IsKeyChordPressed(ImGuiKeyChord key_chord); // was key chord (mods + key) pressed, e.g. you can pass 'ImGuiMod_Ctrl | ImGuiKey_S' as a key-chord. This doesn't do any routing or focus check, please consider using Shortcut() function instead.
|
||||
IMGUI_API int GetKeyPressedAmount(ImGuiKey key, float repeat_delay, float rate); // uses provided repeat rate/delay. return a count, most often 0 or 1 but might be >1 if RepeatRate is small enough that DeltaTime > RepeatRate
|
||||
IMGUI_API const char* GetKeyName(ImGuiKey key); // [DEBUG] returns English name of the key. Those names are provided for debugging purpose and are not meant to be saved persistently nor compared.
|
||||
IMGUI_API void SetNextFrameWantCaptureKeyboard(bool want_capture_keyboard); // Override io.WantCaptureKeyboard flag next frame (said flag is left for your application to handle, typically when true it instructs your app to ignore inputs). e.g. force capture keyboard when your widget is being hovered. This is equivalent to setting "io.WantCaptureKeyboard = want_capture_keyboard"; after the next NewFrame() call.
|
||||
|
||||
// Inputs Utilities: Shortcut Testing & Routing [BETA]
|
||||
// Inputs Utilities: Shortcut Testing & Routing
|
||||
// - Typical use is e.g.: 'if (ImGui::Shortcut(ImGuiMod_Ctrl | ImGuiKey_S)) { ... }'.
|
||||
// - Flags: Default route use ImGuiInputFlags_RouteFocused, but see ImGuiInputFlags_RouteGlobal and other options in ImGuiInputFlags_!
|
||||
// - Flags: Use ImGuiInputFlags_Repeat to support repeat.
|
||||
// - ImGuiKeyChord = a ImGuiKey + optional ImGuiMod_Alt/ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Super.
|
||||
// ImGuiKey_C // Accepted by functions taking ImGuiKey or ImGuiKeyChord arguments
|
||||
// ImGuiMod_Ctrl | ImGuiKey_C // Accepted by functions taking ImGuiKeyChord arguments
|
||||
@@ -1071,8 +1078,10 @@ namespace ImGui
|
||||
// The whole system is order independent, so if Child1 makes its calls before Parent, results will be identical.
|
||||
// This is an important property as it facilitate working with foreign code or larger codebase.
|
||||
// - To understand the difference:
|
||||
// - IsKeyChordPressed() compares mods and call IsKeyPressed() -> function has no side-effect.
|
||||
// - Shortcut() submits a route, routes are resolved, if it currently can be routed it calls IsKeyChordPressed() -> function has (desirable) side-effects as it can prevents another call from getting the route.
|
||||
// - IsKeyChordPressed() compares mods and call IsKeyPressed()
|
||||
// -> the function has no side-effect.
|
||||
// - Shortcut() submits a route, routes are resolved, if it currently can be routed it calls IsKeyChordPressed()
|
||||
// -> the function has (desirable) side-effects as it can prevents another call from getting the route.
|
||||
// - Visualize registered routes in 'Metrics/Debugger->Inputs'.
|
||||
IMGUI_API bool Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags = 0);
|
||||
IMGUI_API void SetNextItemShortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags = 0);
|
||||
@@ -1122,7 +1131,9 @@ namespace ImGui
|
||||
IMGUI_API const char* SaveIniSettingsToMemory(size_t* out_ini_size = NULL); // return a zero-terminated string with the .ini data which you can save by your own mean. call when io.WantSaveIniSettings is set, then save data by your own mean and clear io.WantSaveIniSettings.
|
||||
|
||||
// Debug Utilities
|
||||
// - Your main debugging friend is the ShowMetricsWindow() function, which is also accessible from Demo->Tools->Metrics Debugger
|
||||
// - Your main debugging friend is the ShowMetricsWindow() function.
|
||||
// - Interactive tools are all accessible from the 'Dear ImGui Demo->Tools' menu.
|
||||
// - Read https://github.com/ocornut/imgui/wiki/Debug-Tools for a description of all available debug tools.
|
||||
IMGUI_API void DebugTextEncoding(const char* text);
|
||||
IMGUI_API void DebugFlashStyleColor(ImGuiCol idx);
|
||||
IMGUI_API void DebugStartItemPicker();
|
||||
@@ -1218,7 +1229,7 @@ enum ImGuiChildFlags_
|
||||
};
|
||||
|
||||
// Flags for ImGui::PushItemFlag()
|
||||
// (Those are shared by all items)
|
||||
// (Those are shared by all submitted items)
|
||||
enum ImGuiItemFlags_
|
||||
{
|
||||
ImGuiItemFlags_None = 0, // (Default)
|
||||
@@ -1228,6 +1239,7 @@ enum ImGuiItemFlags_
|
||||
ImGuiItemFlags_ButtonRepeat = 1 << 3, // false // Any button-like behavior will have repeat mode enabled (based on io.KeyRepeatDelay and io.KeyRepeatRate values). Note that you can also call IsItemActive() after any button to tell if it is being held.
|
||||
ImGuiItemFlags_AutoClosePopups = 1 << 4, // true // MenuItem()/Selectable() automatically close their parent popup window.
|
||||
ImGuiItemFlags_AllowDuplicateId = 1 << 5, // false // Allow submitting an item with the same identifier as an item already submitted this frame without triggering a warning tooltip if io.ConfigDebugHighlightIdConflicts is set.
|
||||
ImGuiItemFlags_Disabled = 1 << 6, // false // [Internal] Disable interactions. DOES NOT affect visuals. This is used by BeginDisabled()/EndDisabled() and only provided here so you can read back via GetItemFlags().
|
||||
};
|
||||
|
||||
// Flags for ImGui::InputText()
|
||||
@@ -1320,21 +1332,14 @@ enum ImGuiTreeNodeFlags_
|
||||
};
|
||||
|
||||
// Flags for OpenPopup*(), BeginPopupContext*(), IsPopupOpen() functions.
|
||||
// - To be backward compatible with older API which took an 'int mouse_button = 1' argument instead of 'ImGuiPopupFlags flags',
|
||||
// we need to treat small flags values as a mouse button index, so we encode the mouse button in the first few bits of the flags.
|
||||
// It is therefore guaranteed to be legal to pass a mouse button index in ImGuiPopupFlags.
|
||||
// - For the same reason, we exceptionally default the ImGuiPopupFlags argument of BeginPopupContextXXX functions to 1 instead of 0.
|
||||
// IMPORTANT: because the default parameter is 1 (==ImGuiPopupFlags_MouseButtonRight), if you rely on the default parameter
|
||||
// and want to use another flag, you need to pass in the ImGuiPopupFlags_MouseButtonRight flag explicitly.
|
||||
// - IMPORTANT: If you ever used the left mouse button with BeginPopupContextXXX() helpers before 1.92.6: Read "API BREAKING CHANGES" 2026/01/07 (1.92.6) entry in imgui.cpp or GitHub topic #9157.
|
||||
// - Multiple buttons currently cannot be combined/or-ed in those functions (we could allow it later).
|
||||
enum ImGuiPopupFlags_
|
||||
{
|
||||
ImGuiPopupFlags_None = 0,
|
||||
ImGuiPopupFlags_MouseButtonLeft = 0, // For BeginPopupContext*(): open on Left Mouse release. Guaranteed to always be == 0 (same as ImGuiMouseButton_Left)
|
||||
ImGuiPopupFlags_MouseButtonRight = 1, // For BeginPopupContext*(): open on Right Mouse release. Guaranteed to always be == 1 (same as ImGuiMouseButton_Right)
|
||||
ImGuiPopupFlags_MouseButtonMiddle = 2, // For BeginPopupContext*(): open on Middle Mouse release. Guaranteed to always be == 2 (same as ImGuiMouseButton_Middle)
|
||||
ImGuiPopupFlags_MouseButtonMask_ = 0x1F,
|
||||
ImGuiPopupFlags_MouseButtonDefault_ = 1,
|
||||
ImGuiPopupFlags_MouseButtonLeft = 1 << 2, // For BeginPopupContext*(): open on Left Mouse release. Only one button allowed!
|
||||
ImGuiPopupFlags_MouseButtonRight = 2 << 2, // For BeginPopupContext*(): open on Right Mouse release. Only one button allowed! (default)
|
||||
ImGuiPopupFlags_MouseButtonMiddle = 3 << 2, // For BeginPopupContext*(): open on Middle Mouse release. Only one button allowed!
|
||||
ImGuiPopupFlags_NoReopen = 1 << 5, // For OpenPopup*(), BeginPopupContext*(): don't reopen same popup if already open (won't reposition, won't reinitialize navigation)
|
||||
//ImGuiPopupFlags_NoReopenAlwaysNavInit = 1 << 6, // For OpenPopup*(), BeginPopupContext*(): focus and initialize navigation even when not reopening.
|
||||
ImGuiPopupFlags_NoOpenOverExistingPopup = 1 << 7, // For OpenPopup*(), BeginPopupContext*(): don't open if there's already a popup at the same level of the popup stack
|
||||
@@ -1342,6 +1347,9 @@ enum ImGuiPopupFlags_
|
||||
ImGuiPopupFlags_AnyPopupId = 1 << 10, // For IsPopupOpen(): ignore the ImGuiID parameter and test for any popup.
|
||||
ImGuiPopupFlags_AnyPopupLevel = 1 << 11, // For IsPopupOpen(): search/test at any level of the popup stack (default test in the current level)
|
||||
ImGuiPopupFlags_AnyPopup = ImGuiPopupFlags_AnyPopupId | ImGuiPopupFlags_AnyPopupLevel,
|
||||
ImGuiPopupFlags_MouseButtonShift_ = 2, // [Internal]
|
||||
ImGuiPopupFlags_MouseButtonMask_ = 0x0C, // [Internal]
|
||||
ImGuiPopupFlags_InvalidMask_ = 0x03, // [Internal] Reserve legacy bits 0-1 to detect incorrectly passing 1 or 2 to the function.
|
||||
};
|
||||
|
||||
// Flags for ImGui::Selectable()
|
||||
@@ -1538,7 +1546,7 @@ enum ImGuiSortDirection : ImU8
|
||||
// All our named keys are >= 512. Keys value 0 to 511 are left unused and were legacy native/opaque key values (< 1.87).
|
||||
// Support for legacy keys was completely removed in 1.91.5.
|
||||
// Read details about the 1.87+ transition : https://github.com/ocornut/imgui/issues/4921
|
||||
// Note that "Keys" related to physical keys and are not the same concept as input "Characters", the later are submitted via io.AddInputCharacter().
|
||||
// Note that "Keys" related to physical keys and are not the same concept as input "Characters", the latter are submitted via io.AddInputCharacter().
|
||||
// The keyboard key enum values are named after the keys on a standard US keyboard, and on other keyboard types the keys reported may not match the keycaps.
|
||||
enum ImGuiKey : int
|
||||
{
|
||||
@@ -1695,7 +1703,7 @@ enum ImGuiInputFlags_
|
||||
enum ImGuiConfigFlags_
|
||||
{
|
||||
ImGuiConfigFlags_None = 0,
|
||||
ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. Enable full Tabbing + directional arrows + space/enter to activate.
|
||||
ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. Enable full Tabbing + directional arrows + Space/Enter to activate. Note: some features such as basic Tabbing and CtrL+Tab are enabled by regardless of this flag (and may be disabled via other means, see #4828, #9218).
|
||||
ImGuiConfigFlags_NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. Backend also needs to set ImGuiBackendFlags_HasGamepad.
|
||||
ImGuiConfigFlags_NoMouse = 1 << 4, // Instruct dear imgui to disable mouse inputs and interactions.
|
||||
ImGuiConfigFlags_NoMouseCursorChange = 1 << 5, // Instruct backend to not alter mouse cursor shape and visibility. Use if the backend cursor changes are interfering with yours and you don't want to use SetMouseCursor() to change mouse cursor. You may want to honor requests from imgui by reading GetMouseCursor() yourself instead.
|
||||
@@ -1829,6 +1837,7 @@ enum ImGuiStyleVar_
|
||||
ImGuiStyleVar_ScrollbarPadding, // float ScrollbarPadding
|
||||
ImGuiStyleVar_GrabMinSize, // float GrabMinSize
|
||||
ImGuiStyleVar_GrabRounding, // float GrabRounding
|
||||
ImGuiStyleVar_ImageRounding, // float ImageRounding
|
||||
ImGuiStyleVar_ImageBorderSize, // float ImageBorderSize
|
||||
ImGuiStyleVar_TabRounding, // float TabRounding
|
||||
ImGuiStyleVar_TabBorderSize, // float TabBorderSize
|
||||
@@ -1871,19 +1880,20 @@ enum ImGuiColorEditFlags_
|
||||
ImGuiColorEditFlags_NoTooltip = 1 << 6, // // ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview.
|
||||
ImGuiColorEditFlags_NoLabel = 1 << 7, // // ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker).
|
||||
ImGuiColorEditFlags_NoSidePreview = 1 << 8, // // ColorPicker: disable bigger color preview on right side of the picker, use small color square preview instead.
|
||||
ImGuiColorEditFlags_NoDragDrop = 1 << 9, // // ColorEdit: disable drag and drop target. ColorButton: disable drag and drop source.
|
||||
ImGuiColorEditFlags_NoDragDrop = 1 << 9, // // ColorEdit: disable drag and drop target/source. ColorButton: disable drag and drop source.
|
||||
ImGuiColorEditFlags_NoBorder = 1 << 10, // // ColorButton: disable border (which is enforced by default)
|
||||
ImGuiColorEditFlags_NoColorMarkers = 1 << 11, // // ColorEdit: disable rendering R/G/B/A color marker. May also be disabled globally by setting style.ColorMarkerSize = 0.
|
||||
|
||||
// Alpha preview
|
||||
// - Prior to 1.91.8 (2025/01/21): alpha was made opaque in the preview by default using old name ImGuiColorEditFlags_AlphaPreview.
|
||||
// - We now display the preview as transparent by default. You can use ImGuiColorEditFlags_AlphaOpaque to use old behavior.
|
||||
// - The new flags may be combined better and allow finer controls.
|
||||
ImGuiColorEditFlags_AlphaOpaque = 1 << 11, // // ColorEdit, ColorPicker, ColorButton: disable alpha in the preview,. Contrary to _NoAlpha it may still be edited when calling ColorEdit4()/ColorPicker4(). For ColorButton() this does the same as _NoAlpha.
|
||||
ImGuiColorEditFlags_AlphaNoBg = 1 << 12, // // ColorEdit, ColorPicker, ColorButton: disable rendering a checkerboard background behind transparent color.
|
||||
ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 13, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half transparent preview.
|
||||
ImGuiColorEditFlags_AlphaOpaque = 1 << 12, // // ColorEdit, ColorPicker, ColorButton: disable alpha in the preview,. Contrary to _NoAlpha it may still be edited when calling ColorEdit4()/ColorPicker4(). For ColorButton() this does the same as _NoAlpha.
|
||||
ImGuiColorEditFlags_AlphaNoBg = 1 << 13, // // ColorEdit, ColorPicker, ColorButton: disable rendering a checkerboard background behind transparent color.
|
||||
ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 14, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half transparent preview.
|
||||
|
||||
// User Options (right-click on widget to change some of them).
|
||||
ImGuiColorEditFlags_AlphaBar = 1 << 16, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker.
|
||||
ImGuiColorEditFlags_AlphaBar = 1 << 18, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker.
|
||||
ImGuiColorEditFlags_HDR = 1 << 19, // // (WIP) ColorEdit: Currently only disable 0.0f..1.0f limits in RGBA edition (note: you probably want to use ImGuiColorEditFlags_Float flag as well).
|
||||
ImGuiColorEditFlags_DisplayRGB = 1 << 20, // [Display] // ColorEdit: override _display_ type among RGB/HSV/Hex. ColorPicker: select any combination using one or more of RGB/HSV/Hex.
|
||||
ImGuiColorEditFlags_DisplayHSV = 1 << 21, // [Display] // "
|
||||
@@ -1926,8 +1936,9 @@ enum ImGuiSliderFlags_
|
||||
ImGuiSliderFlags_ClampOnInput = 1 << 9, // Clamp value to min/max bounds when input manually with Ctrl+Click. By default Ctrl+Click allows going out of bounds.
|
||||
ImGuiSliderFlags_ClampZeroRange = 1 << 10, // Clamp even if min==max==0.0f. Otherwise due to legacy reason DragXXX functions don't clamp with those values. When your clamping limits are dynamic you almost always want to use it.
|
||||
ImGuiSliderFlags_NoSpeedTweaks = 1 << 11, // Disable keyboard modifiers altering tweak speed. Useful if you want to alter tweak speed yourself based on your own logic.
|
||||
ImGuiSliderFlags_ColorMarkers = 1 << 12, // DragScalarN(), SliderScalarN(): Draw R/G/B/A color markers on each component.
|
||||
ImGuiSliderFlags_AlwaysClamp = ImGuiSliderFlags_ClampOnInput | ImGuiSliderFlags_ClampZeroRange,
|
||||
ImGuiSliderFlags_InvalidMask_ = 0x7000000F, // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast to this enum, and will trigger an assert if needed.
|
||||
ImGuiSliderFlags_InvalidMask_ = 0x7000000F, // [Internal] We treat using those bits as being potentially a 'float power' argument from legacy API (obsoleted 2020-08) that has got miscast to this enum, and will trigger an assert if needed.
|
||||
};
|
||||
|
||||
// Identify a mouse button.
|
||||
@@ -2017,7 +2028,7 @@ enum ImGuiTableFlags_
|
||||
ImGuiTableFlags_Reorderable = 1 << 1, // Enable reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers)
|
||||
ImGuiTableFlags_Hideable = 1 << 2, // Enable hiding/disabling columns in context menu.
|
||||
ImGuiTableFlags_Sortable = 1 << 3, // Enable sorting. Call TableGetSortSpecs() to obtain sort specs. Also see ImGuiTableFlags_SortMulti and ImGuiTableFlags_SortTristate.
|
||||
ImGuiTableFlags_NoSavedSettings = 1 << 4, // Disable persisting columns order, width and sort settings in the .ini file.
|
||||
ImGuiTableFlags_NoSavedSettings = 1 << 4, // Disable persisting columns order, width, visibility and sort settings in the .ini file.
|
||||
ImGuiTableFlags_ContextMenuInBody = 1 << 5, // Right-click on columns body/contents will display table context menu. By default it is available in TableHeadersRow().
|
||||
// Decorations
|
||||
ImGuiTableFlags_RowBg = 1 << 6, // Set each RowBg color with ImGuiCol_TableRowBg or ImGuiCol_TableRowBgAlt (equivalent of calling TableSetBgColor with ImGuiTableBgFlags_RowBg0 on each row manually)
|
||||
@@ -2133,7 +2144,7 @@ struct ImGuiTableSortSpecs
|
||||
int SpecsCount; // Sort spec count. Most often 1. May be > 1 when ImGuiTableFlags_SortMulti is enabled. May be == 0 when ImGuiTableFlags_SortTristate is enabled.
|
||||
bool SpecsDirty; // Set to true when specs have changed since last time! Use this to sort again, then clear the flag.
|
||||
|
||||
ImGuiTableSortSpecs() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiTableSortSpecs() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Sorting specification for one column of a table (sizeof == 12 bytes)
|
||||
@@ -2144,7 +2155,7 @@ struct ImGuiTableColumnSortSpecs
|
||||
ImS16 SortOrder; // Index within parent ImGuiTableSortSpecs (always stored in order starting from 0, tables sorted on a single criteria will always have a 0 here)
|
||||
ImGuiSortDirection SortDirection; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending
|
||||
|
||||
ImGuiTableColumnSortSpecs() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiTableColumnSortSpecs() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2267,7 +2278,7 @@ struct ImGuiStyle
|
||||
// - recap: ImGui::GetFontSize() == FontSizeBase * (FontScaleMain * FontScaleDpi * other_scaling_factors)
|
||||
float FontSizeBase; // Current base font size before external global factors are applied. Use PushFont(NULL, size) to modify. Use ImGui::GetFontSize() to obtain scaled value.
|
||||
float FontScaleMain; // Main global scale factor. May be set by application once, or exposed to end-user.
|
||||
float FontScaleDpi; // Additional global scale factor from viewport/monitor contents scale. When io.ConfigDpiScaleFonts is enabled, this is automatically overwritten when changing monitor DPI.
|
||||
float FontScaleDpi; // Additional global scale factor from viewport/monitor contents scale. In docking branch: when io.ConfigDpiScaleFonts is enabled, this is automatically overwritten when changing monitor DPI.
|
||||
|
||||
float Alpha; // Global alpha applies to everything in Dear ImGui.
|
||||
float DisabledAlpha; // Additional alpha multiplier applied by BeginDisabled(). Multiply over current value of Alpha.
|
||||
@@ -2297,6 +2308,7 @@ struct ImGuiStyle
|
||||
float GrabMinSize; // Minimum width/height of a grab box for slider/scrollbar.
|
||||
float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
|
||||
float LogSliderDeadzone; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero.
|
||||
float ImageRounding; // Rounding of Image() calls.
|
||||
float ImageBorderSize; // Thickness of border around Image() calls.
|
||||
float TabRounding; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
|
||||
float TabBorderSize; // Thickness of border around tabs.
|
||||
@@ -2314,6 +2326,7 @@ struct ImGuiStyle
|
||||
float DragDropTargetRounding; // Radius of the drag and drop target frame.
|
||||
float DragDropTargetBorderSize; // Thickness of the drag and drop target border.
|
||||
float DragDropTargetPadding; // Size to expand the drag and drop target from actual target item size.
|
||||
float ColorMarkerSize; // Size of R/G/B/A color markers for ColorEdit4() and for Drags/Sliders when using ImGuiSliderFlags_ColorMarkers.
|
||||
ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
|
||||
ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered).
|
||||
ImVec2 SelectableTextAlign; // Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line.
|
||||
@@ -2434,7 +2447,7 @@ struct ImGuiIO
|
||||
|
||||
// Options to configure Error Handling and how we handle recoverable errors [EXPERIMENTAL]
|
||||
// - Error recovery is provided as a way to facilitate:
|
||||
// - Recovery after a programming error (native code or scripting language - the later tends to facilitate iterating on code while running).
|
||||
// - Recovery after a programming error (native code or scripting language - the latter tends to facilitate iterating on code while running).
|
||||
// - Recovery after running an exception handler or any error processing which may skip code after an error has been detected.
|
||||
// - Error recovery is not perfect nor guaranteed! It is a feature to ease development.
|
||||
// You not are not supposed to rely on it in the course of a normal application run.
|
||||
@@ -2623,18 +2636,20 @@ struct ImGuiInputTextCallbackData
|
||||
ImGuiInputTextFlags EventFlag; // One ImGuiInputTextFlags_Callback* // Read-only
|
||||
ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only
|
||||
void* UserData; // What user passed to InputText() // Read-only
|
||||
ImGuiID ID; // Widget ID // Read-only
|
||||
|
||||
// Arguments for the different callback events
|
||||
// - During Resize callback, Buf will be same as your input buffer.
|
||||
// - However, during Completion/History/Always callback, Buf always points to our own internal data (it is not the same as your buffer)! Changes to it will be reflected into your own buffer shortly after the callback.
|
||||
// - To modify the text buffer in a callback, prefer using the InsertChars() / DeleteChars() function. InsertChars() will take care of calling the resize callback if necessary.
|
||||
// - If you know your edits are not going to resize the underlying buffer allocation, you may modify the contents of 'Buf[]' directly. You need to update 'BufTextLen' accordingly (0 <= BufTextLen < BufSize) and set 'BufDirty'' to true so InputText can update its internal state.
|
||||
ImWchar EventChar; // Character input // Read-write // [CharFilter] Replace character with another one, or set to zero to drop. return 1 is equivalent to setting EventChar=0;
|
||||
ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only // [Completion,History]
|
||||
ImWchar EventChar; // Character input // Read-write // [CharFilter] Replace character with another one, or set to zero to drop. return 1 is equivalent to setting EventChar=0;
|
||||
bool EventActivated; // Input field just got activated // Read-only // [Always]
|
||||
bool BufDirty; // Set if you modify Buf/BufTextLen! // Write // [Completion,History,Always]
|
||||
char* Buf; // Text buffer // Read-write // [Resize] Can replace pointer / [Completion,History,Always] Only write to pointed data, don't replace the actual pointer!
|
||||
int BufTextLen; // Text length (in bytes) // Read-write // [Resize,Completion,History,Always] Exclude zero-terminator storage. In C land: == strlen(some_text), in C++ land: string.length()
|
||||
int BufSize; // Buffer size (in bytes) = capacity+1 // Read-only // [Resize,Completion,History,Always] Include zero-terminator storage. In C land: == ARRAYSIZE(my_char_array), in C++ land: string.capacity()+1
|
||||
bool BufDirty; // Set if you modify Buf/BufTextLen! // Write // [Completion,History,Always]
|
||||
int CursorPos; // // Read-write // [Completion,History,Always]
|
||||
int SelectionStart; // // Read-write // [Completion,History,Always] == to SelectionEnd when no selection
|
||||
int SelectionEnd; // // Read-write // [Completion,History,Always]
|
||||
@@ -2644,9 +2659,10 @@ struct ImGuiInputTextCallbackData
|
||||
IMGUI_API ImGuiInputTextCallbackData();
|
||||
IMGUI_API void DeleteChars(int pos, int bytes_count);
|
||||
IMGUI_API void InsertChars(int pos, const char* text, const char* text_end = NULL);
|
||||
void SelectAll() { SelectionStart = 0; SelectionEnd = BufTextLen; }
|
||||
void ClearSelection() { SelectionStart = SelectionEnd = BufTextLen; }
|
||||
bool HasSelection() const { return SelectionStart != SelectionEnd; }
|
||||
void SelectAll() { SelectionStart = 0; CursorPos = SelectionEnd = BufTextLen; }
|
||||
void SetSelection(int s, int e) { IM_ASSERT(s >= 0 && s <= BufTextLen); IM_ASSERT(e >= 0 && e <= BufTextLen); SelectionStart = s; CursorPos = SelectionEnd = e; }
|
||||
void ClearSelection() { SelectionStart = SelectionEnd = BufTextLen; }
|
||||
bool HasSelection() const { return SelectionStart != SelectionEnd; }
|
||||
};
|
||||
|
||||
// Resizing callback data to apply custom constraint. As enabled by SetNextWindowSizeConstraints(). Callback is called during the next Begin().
|
||||
@@ -2865,7 +2881,7 @@ struct ImGuiListClipper
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
//inline void IncludeRangeByIndices(int item_begin, int item_end) { IncludeItemsByIndex(item_begin, item_end); } // [renamed in 1.89.9]
|
||||
//inline void ForceDisplayRangeByIndices(int item_begin, int item_end) { IncludeItemsByIndex(item_begin, item_end); } // [renamed in 1.89.6]
|
||||
//inline ImGuiListClipper(int items_count, float items_height = -1.0f) { memset(this, 0, sizeof(*this)); ItemsCount = -1; Begin(items_count, items_height); } // [removed in 1.79]
|
||||
//inline ImGuiListClipper(int items_count, float items_height = -1.0f) { memset((void*)this, 0, sizeof(*this)); ItemsCount = -1; Begin(items_count, items_height); } // [removed in 1.79]
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -3150,7 +3166,7 @@ struct ImDrawCmd
|
||||
int UserCallbackDataSize; // 4 // Size of callback user data when using storage, otherwise 0.
|
||||
int UserCallbackDataOffset;// 4 // [Internal] Offset of callback user data when using storage, otherwise -1.
|
||||
|
||||
ImDrawCmd() { memset(this, 0, sizeof(*this)); } // Also ensure our padding fields are zeroed
|
||||
ImDrawCmd() { memset((void*)this, 0, sizeof(*this)); } // Also ensure our padding fields are zeroed
|
||||
|
||||
// Since 1.83: returns ImTextureID associated with this draw call. Warning: DO NOT assume this is always same as 'TextureId' (we will change this function for an upcoming feature)
|
||||
// Since 1.92: removed ImDrawCmd::TextureId field, the getter function must be used!
|
||||
@@ -3196,7 +3212,7 @@ struct ImDrawListSplitter
|
||||
int _Count; // Number of active channels (1+)
|
||||
ImVector<ImDrawChannel> _Channels; // Draw channels (not resized down so _Count might be < Channels.Size)
|
||||
|
||||
inline ImDrawListSplitter() { memset(this, 0, sizeof(*this)); }
|
||||
inline ImDrawListSplitter() { memset((void*)this, 0, sizeof(*this)); }
|
||||
inline ~ImDrawListSplitter() { ClearFreeMemory(); }
|
||||
inline void Clear() { _Current = 0; _Count = 1; } // Do not clear Channels[] so our allocations are reused next frame
|
||||
IMGUI_API void ClearFreeMemory();
|
||||
@@ -3489,7 +3505,7 @@ struct ImTextureData
|
||||
bool WantDestroyNextFrame; // rw - // [Internal] Queued to set ImTextureStatus_WantDestroy next frame. May still be used in the current frame.
|
||||
|
||||
// Functions
|
||||
ImTextureData() { memset(this, 0, sizeof(*this)); Status = ImTextureStatus_Destroyed; TexID = ImTextureID_Invalid; }
|
||||
ImTextureData() { memset((void*)this, 0, sizeof(*this)); Status = ImTextureStatus_Destroyed; TexID = ImTextureID_Invalid; }
|
||||
~ImTextureData() { DestroyPixels(); }
|
||||
IMGUI_API void Create(ImTextureFormat format, int w, int h);
|
||||
IMGUI_API void DestroyPixels();
|
||||
@@ -3504,7 +3520,7 @@ struct ImTextureData
|
||||
// - Call SetTexID() and SetStatus() after honoring texture requests. Never modify TexID and Status directly!
|
||||
// - A backend may decide to destroy a texture that we did not request to destroy, which is fine (e.g. freeing resources), but we immediately set the texture back in _WantCreate mode.
|
||||
void SetTexID(ImTextureID tex_id) { TexID = tex_id; }
|
||||
void SetStatus(ImTextureStatus status) { Status = status; if (status == ImTextureStatus_Destroyed && !WantDestroyNextFrame) Status = ImTextureStatus_WantCreate; }
|
||||
void SetStatus(ImTextureStatus status) { Status = status; if (status == ImTextureStatus_Destroyed && !WantDestroyNextFrame && Pixels != nullptr) Status = ImTextureStatus_WantCreate; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -3518,16 +3534,15 @@ struct ImFontConfig
|
||||
char Name[40]; // <auto> // Name (strictly to ease debugging, hence limited size buffer)
|
||||
void* FontData; // // TTF/OTF data
|
||||
int FontDataSize; // // TTF/OTF data size
|
||||
bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the owner ImFontAtlas (will delete memory itself).
|
||||
bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the owner ImFontAtlas (will delete memory itself). SINCE 1.92, THE DATA NEEDS TO PERSIST FOR WHOLE DURATION OF ATLAS.
|
||||
|
||||
// Options
|
||||
bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
|
||||
bool PixelSnapH; // false // Align every glyph AdvanceX to pixel boundaries. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.
|
||||
bool PixelSnapV; // true // Align Scaled GlyphOffset.y to pixel boundaries.
|
||||
bool PixelSnapH; // false // Align every glyph AdvanceX to pixel boundaries. Prevents fractional font size from working correctly! Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, OversampleH/V will default to 1.
|
||||
ImS8 OversampleH; // 0 (2) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1 or 2 depending on size. Note the difference between 2 and 3 is minimal. You can reduce this to 1 for large glyphs save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
|
||||
ImS8 OversampleV; // 0 (1) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1. This is not really useful as we don't use sub-pixel positions on the Y axis.
|
||||
ImWchar EllipsisChar; // 0 // Explicitly specify Unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
|
||||
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
|
||||
float SizePixels; // // Output size in pixels for rasterizer (more or less maps to the resulting font height).
|
||||
const ImWchar* GlyphRanges; // NULL // *LEGACY* THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list).
|
||||
const ImWchar* GlyphExcludeRanges; // NULL // Pointer to a small user-provided list of Unicode ranges (2 value per range, values are inclusive, zero-terminated list). This is very close to GlyphRanges[] but designed to exclude ranges from a font source, when merging fonts with overlapping glyphs. Use "Input Glyphs Overlap Detection Tool" to find about your overlapping ranges.
|
||||
//ImVec2 GlyphExtraSpacing; // 0, 0 // (REMOVED AT IT SEEMS LARGELY OBSOLETE. PLEASE REPORT IF YOU WERE USING THIS). Extra spacing (in pixels) between glyphs when rendered: essentially add to glyph->AdvanceX. Only X axis is supported for now.
|
||||
@@ -3537,9 +3552,11 @@ struct ImFontConfig
|
||||
float GlyphExtraAdvanceX; // 0 // Extra spacing (in pixels) between glyphs. Please contact us if you are using this. // FIXME-NEWATLAS: Intentionally unscaled
|
||||
ImU32 FontNo; // 0 // Index of font within TTF/OTF file
|
||||
unsigned int FontLoaderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure.
|
||||
//unsigned int FontBuilderFlags; // -- // [Renamed in 1.92] Ue FontLoaderFlags.
|
||||
//unsigned int FontBuilderFlags; // -- // [Renamed in 1.92] Use FontLoaderFlags.
|
||||
float RasterizerMultiply; // 1.0f // Linearly brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. This is a silly thing we may remove in the future.
|
||||
float RasterizerDensity; // 1.0f // [LEGACY: this only makes sense when ImGuiBackendFlags_RendererHasTextures is not supported] DPI scale multiplier for rasterization. Not altering other font metrics: makes it easy to swap between e.g. a 100% and a 400% fonts for a zooming display, or handle Retina screen. IMPORTANT: If you change this it is expected that you increase/decrease font scale roughly to the inverse of this, otherwise quality may look lowered.
|
||||
float ExtraSizeScale; // 1.0f // Extra rasterizer scale over SizePixels.
|
||||
float LineHeight; // 1.0f // [PCSX2 Custom] The spacing between lines of the font, in ems.
|
||||
|
||||
// [Internal]
|
||||
ImFontFlags Flags; // Font flags (don't use just yet, will be exposed in upcoming 1.92.X updates)
|
||||
@@ -3547,6 +3564,9 @@ struct ImFontConfig
|
||||
const ImFontLoader* FontLoader; // Custom font backend for this source (default source is the one stored in ImFontAtlas)
|
||||
void* FontLoaderData; // Font loader opaque storage (per font config)
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
bool PixelSnapV; // true // [Obsoleted in 1.91.6] Align Scaled GlyphOffset.y to pixel boundaries.
|
||||
#endif
|
||||
IMGUI_API ImFontConfig();
|
||||
};
|
||||
|
||||
@@ -3563,7 +3583,7 @@ struct ImFontGlyph
|
||||
float U0, V0, U1, V1; // Texture coordinates for the current value of ImFontAtlas->TexRef. Cached equivalent of calling GetCustomRect() with PackId.
|
||||
int PackId; // [Internal] ImFontAtlasRectId value (FIXME: Cold data, could be moved elsewhere?)
|
||||
|
||||
ImFontGlyph() { memset(this, 0, sizeof(*this)); PackId = -1; }
|
||||
ImFontGlyph() { memset((void*)this, 0, sizeof(*this)); PackId = -1; }
|
||||
};
|
||||
|
||||
// Helper to build glyph ranges from text/string data. Feed your application strings/characters to it then call BuildRanges().
|
||||
@@ -3596,7 +3616,7 @@ struct ImFontAtlasRect
|
||||
unsigned short w, h; // Size
|
||||
ImVec2 uv0, uv1; // UV coordinates (in current texture)
|
||||
|
||||
ImFontAtlasRect() { memset(this, 0, sizeof(*this)); }
|
||||
ImFontAtlasRect() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Flags for ImFontAtlas build
|
||||
@@ -3632,7 +3652,9 @@ struct ImFontAtlas
|
||||
IMGUI_API ImFontAtlas();
|
||||
IMGUI_API ~ImFontAtlas();
|
||||
IMGUI_API ImFont* AddFont(const ImFontConfig* font_cfg);
|
||||
IMGUI_API ImFont* AddFontDefault(const ImFontConfig* font_cfg = NULL);
|
||||
IMGUI_API ImFont* AddFontDefault(const ImFontConfig* font_cfg = NULL); // Selects between AddFontDefaultVector() and AddFontDefaultBitmap().
|
||||
IMGUI_API ImFont* AddFontDefaultVector(const ImFontConfig* font_cfg = NULL); // Embedded scalable font. Recommended at any higher size.
|
||||
IMGUI_API ImFont* AddFontDefaultBitmap(const ImFontConfig* font_cfg = NULL); // Embedded classic pixel-clean font. Recommended at Size 13px with no scaling.
|
||||
IMGUI_API ImFont* AddFontFromFileTTF(const char* filename, float size_pixels = 0.0f, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL);
|
||||
IMGUI_API ImFont* AddFontFromMemoryTTF(void* font_data, int font_data_size, float size_pixels = 0.0f, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // Note: Transfer ownership of 'ttf_data' to ImFontAtlas! Will be deleted after destruction of the atlas. Set font_cfg->FontDataOwnedByAtlas=false to keep ownership of your data and it won't be freed.
|
||||
IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_data_size, float size_pixels = 0.0f, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp.
|
||||
@@ -3794,7 +3816,7 @@ struct ImFontBaked
|
||||
unsigned int MetricsTotalSurface:26;// 3 // out // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
|
||||
unsigned int WantDestroy:1; // 0 // // Queued for destroy
|
||||
unsigned int LoadNoFallback:1; // 0 // // Disable loading fallback in lower-level calls.
|
||||
unsigned int LoadNoRenderOnLayout:1;// 0 // // Enable a two-steps mode where CalcTextSize() calls will load AdvanceX *without* rendering/packing glyphs. Only advantagous if you know that the glyph is unlikely to actually be rendered, otherwise it is slower because we'd do one query on the first CalcTextSize and one query on the first Draw.
|
||||
unsigned int LoadNoRenderOnLayout:1;// 0 // // Enable a two-steps mode where CalcTextSize() calls will load AdvanceX *without* rendering/packing glyphs. Only advantageous if you know that the glyph is unlikely to actually be rendered, otherwise it is slower because we'd do one query on the first CalcTextSize and one query on the first Draw.
|
||||
int LastUsedFrame; // 4 // // Record of that time this was bounds
|
||||
ImGuiID BakedId; // 4 // // Unique ID for this baked storage
|
||||
ImFont* OwnerFont; // 4-8 // in // Parent font
|
||||
@@ -3831,16 +3853,17 @@ struct ImFont
|
||||
ImFontAtlas* OwnerAtlas; // 4-8 // What we have been loaded into.
|
||||
ImFontFlags Flags; // 4 // Font flags.
|
||||
float CurrentRasterizerDensity; // Current rasterizer density. This is a varying state of the font.
|
||||
float LineHeight; // 4 // Line Height
|
||||
|
||||
// [Internal] Members: Cold ~24-52 bytes
|
||||
// Conceptually Sources[] is the list of font sources merged to create this font.
|
||||
ImGuiID FontId; // Unique identifier for the font
|
||||
float LegacySize; // 4 // in // Font size passed to AddFont(). Use for old code calling PushFont() expecting to use that size. (use ImGui::GetFontBaked() to get font baked at current bound size).
|
||||
ImVector<ImFontConfig*> Sources; // 16 // in // List of sources. Pointers within OwnerAtlas->Sources[]
|
||||
ImWchar EllipsisChar; // 2-4 // out // Character used for ellipsis rendering ('...').
|
||||
ImWchar EllipsisChar; // 2-4 // out // Character used for ellipsis rendering ('...'). If you ever want to temporarily swap this for an alternative/dummy char, make sure to clear EllipsisAutoBake.
|
||||
ImWchar FallbackChar; // 2-4 // out // Character used if a glyph isn't found (U+FFFD, '?')
|
||||
ImU8 Used8kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/8192/8]; // 1 bytes if ImWchar=ImWchar16, 16 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints.
|
||||
bool EllipsisAutoBake; // 1 // // Mark when the "..." glyph needs to be generated.
|
||||
ImU8 Used8kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/8192/8]; // 1 bytes if ImWchar=ImWchar16, 17 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 8K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints.
|
||||
bool EllipsisAutoBake; // 1 // // Mark when the "..." glyph (== EllipsisChar) needs to be generated by combining multiple '.'.
|
||||
ImGuiStorage RemapPairs; // 16 // // Remapping pairs when using AddRemapChar(), otherwise empty.
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
float Scale; // 4 // in // Legacy base font scale (~1.0f), multiplied by the per-window font scale which you can adjust with SetWindowFontScale()
|
||||
@@ -3923,7 +3946,7 @@ struct ImGuiViewport
|
||||
void* PlatformHandle; // void* to hold higher-level, platform window handle (e.g. HWND, GLFWWindow*, SDL_Window*)
|
||||
void* PlatformHandleRaw; // void* to hold lower-level, platform-native window handle (under Win32 this is expected to be a HWND, unused for other platforms)
|
||||
|
||||
ImGuiViewport() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiViewport() { memset((void*)this, 0, sizeof(*this)); }
|
||||
|
||||
// Helpers
|
||||
ImVec2 GetCenter() const { return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); }
|
||||
@@ -3945,7 +3968,7 @@ struct ImGuiPlatformIO
|
||||
|
||||
// Optional: Access OS clipboard
|
||||
// (default to use native Win32 clipboard on Windows, otherwise uses a private clipboard. Override to access OS clipboard on other architectures)
|
||||
const char* (*Platform_GetClipboardTextFn)(ImGuiContext* ctx);
|
||||
const char* (*Platform_GetClipboardTextFn)(ImGuiContext* ctx); // Should return NULL on failure (e.g. clipboard data is not text).
|
||||
void (*Platform_SetClipboardTextFn)(ImGuiContext* ctx, const char* text);
|
||||
void* Platform_ClipboardUserData;
|
||||
|
||||
@@ -4000,7 +4023,7 @@ struct ImGuiPlatformImeData
|
||||
float InputLineHeight; // Line height (for IME).
|
||||
ImGuiID ViewportId; // ID of platform window/viewport.
|
||||
|
||||
ImGuiPlatformImeData() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiPlatformImeData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -4022,19 +4045,21 @@ namespace ImGui
|
||||
inline void PopButtonRepeat() { PopItemFlag(); }
|
||||
inline void PushTabStop(bool tab_stop) { PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); }
|
||||
inline void PopTabStop() { PopItemFlag(); }
|
||||
// You do not need those functions! See #7838 on GitHub for more info.
|
||||
IMGUI_API ImVec2 GetContentRegionMax(); // Content boundaries max (e.g. window boundaries including scrolling, or current column boundaries). You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()!
|
||||
IMGUI_API ImVec2 GetWindowContentRegionMin(); // Content boundaries min for the window (roughly (0,0)-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()!
|
||||
IMGUI_API ImVec2 GetWindowContentRegionMax(); // Content boundaries max for the window (roughly (0,0)+Size-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()!
|
||||
// OBSOLETED in 1.90.0 (from September 2023)
|
||||
inline bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags window_flags = 0) { return BeginChild(id, size, ImGuiChildFlags_FrameStyle, window_flags); }
|
||||
inline void EndChildFrame() { EndChild(); }
|
||||
//inline bool BeginChild(const char* str_id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags){ return BeginChild(str_id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
|
||||
//inline bool BeginChild(ImGuiID id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags) { return BeginChild(id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
|
||||
inline void ShowStackToolWindow(bool* p_open = NULL) { ShowIDStackToolWindow(p_open); }
|
||||
IMGUI_API bool Combo(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int popup_max_height_in_items = -1);
|
||||
IMGUI_API bool ListBox(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int height_in_items = -1);
|
||||
|
||||
// Some of the older obsolete names along with their replacement (commented out so they are not reported in IDE)
|
||||
// OBSOLETED in 1.90.0 (from September 2023)
|
||||
//inline bool BeginChild(const char* str_id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags) { return BeginChild(str_id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
|
||||
//inline bool BeginChild(ImGuiID id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags) { return BeginChild(id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
|
||||
//inline bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags = 0) { return BeginChild(id, size, ImGuiChildFlags_FrameStyle, flags); }
|
||||
//inline void EndChildFrame() { EndChild(); }
|
||||
//inline void ShowStackToolWindow(bool* p_open = NULL) { ShowIDStackToolWindow(p_open); }
|
||||
// OBSOLETED in 1.89.7 (from June 2023)
|
||||
//IMGUI_API void SetItemAllowOverlap(); // Use SetNextItemAllowOverlap() _before_ item.
|
||||
//-- OBSOLETED in 1.89.4 (from March 2023)
|
||||
@@ -4144,10 +4169,12 @@ typedef ImFontAtlasRect ImFontAtlasCustomRect;
|
||||
//typedef ImGuiKeyChord ImGuiKeyModFlags; // == int
|
||||
//enum ImGuiKeyModFlags_ { ImGuiKeyModFlags_None = 0, ImGuiKeyModFlags_Ctrl = ImGuiMod_Ctrl, ImGuiKeyModFlags_Shift = ImGuiMod_Shift, ImGuiKeyModFlags_Alt = ImGuiMod_Alt, ImGuiKeyModFlags_Super = ImGuiMod_Super };
|
||||
|
||||
#define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER) // OBSOLETED IN 1.90 (now using C++11 standard version)
|
||||
//#define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER) // OBSOLETED IN 1.90 (now using C++11 standard version)
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
|
||||
#define IM_ARRAYSIZE IM_COUNTOF // RENAMED IN 1.92.6: IM_ARRAYSIZE -> IM_COUNTOF
|
||||
|
||||
// RENAMED IMGUI_DISABLE_METRICS_WINDOW > IMGUI_DISABLE_DEBUG_TOOLS in 1.88 (from June 2022)
|
||||
#ifdef IMGUI_DISABLE_METRICS_WINDOW
|
||||
#error IMGUI_DISABLE_METRICS_WINDOW was renamed to IMGUI_DISABLE_DEBUG_TOOLS, please use new name.
|
||||
|
||||
+112
-82
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.5
|
||||
// dear imgui, v1.92.6
|
||||
// (internal structures/api)
|
||||
|
||||
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
|
||||
@@ -60,7 +60,7 @@ Index of this file:
|
||||
#include <limits.h> // INT_MIN, INT_MAX
|
||||
|
||||
// Enable SSE intrinsics if available
|
||||
#if (defined __SSE__ || defined __x86_64__ || defined _M_X64 || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1))) && !defined(IMGUI_DISABLE_SSE)
|
||||
#if (defined __SSE__ || defined __x86_64__ || defined _M_X64 || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1))) && !defined(IMGUI_DISABLE_SSE) && !defined(_M_ARM64) && !defined(_M_ARM64EC)
|
||||
#define IMGUI_ENABLE_SSE
|
||||
#include <immintrin.h>
|
||||
#if (defined __AVX__ || defined __SSE4_2__)
|
||||
@@ -106,6 +106,7 @@ Index of this file:
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion" // warning: conversion to 'xxxx' from 'xxxx' may change the sign of the result
|
||||
#endif
|
||||
|
||||
// In 1.89.4, we moved the implementation of "courtesy maths operators" from imgui_internal.h in imgui.h
|
||||
@@ -276,11 +277,9 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
|
||||
#define IM_MEMALIGN(_OFF,_ALIGN) (((_OFF) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1)) // Memory align e.g. IM_ALIGN(0,4)=0, IM_ALIGN(1,4)=4, IM_ALIGN(4,4)=4, IM_ALIGN(5,4)=8
|
||||
#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose
|
||||
#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
|
||||
#define IM_TRUNC(_VAL) ((float)(int)(_VAL)) // ImTrunc() is not inlined in MSVC debug builds
|
||||
#define IM_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) //
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
#define IM_FLOOR IM_TRUNC // [OBSOLETE] Renamed in 1.90.0 (Sept 2023)
|
||||
#endif
|
||||
#define IM_TRUNC(_VAL) ((float)(int)(_VAL)) // Positive values only! ImTrunc() is not inlined in MSVC debug builds
|
||||
#define IM_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) // Positive values only!
|
||||
//#define IM_FLOOR IM_TRUNC // [OBSOLETE] Renamed in 1.90.0 (Sept 2023)
|
||||
|
||||
// Hint for branch prediction
|
||||
#if (defined(__cplusplus) && (__cplusplus >= 202002L)) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 202002L))
|
||||
@@ -335,7 +334,6 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
|
||||
#define IM_PRIu64 "llu"
|
||||
#define IM_PRIX64 "llX"
|
||||
#endif
|
||||
#define IM_TEXTUREID_TO_U64(_TEXID) ((ImU64)(intptr_t)(_TEXID))
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Generic helpers
|
||||
@@ -442,6 +440,16 @@ IMGUI_API ImVec2 ImFontCalcTextSizeEx(ImFont* font, float size, float max
|
||||
IMGUI_API const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* text, const char* text_end, float wrap_width, ImDrawTextFlags flags = 0);
|
||||
IMGUI_API const char* ImTextCalcWordWrapNextLineStart(const char* text, const char* text_end, ImDrawTextFlags flags = 0); // trim trailing space and find beginning of next line
|
||||
|
||||
// Character classification for word-wrapping logic
|
||||
enum ImWcharClass
|
||||
{
|
||||
ImWcharClass_Blank, ImWcharClass_Punct, ImWcharClass_Other
|
||||
};
|
||||
IMGUI_API void ImTextInitClassifiers();
|
||||
IMGUI_API void ImTextClassifierClear(ImU32* bits, unsigned int codepoint_min, unsigned int codepoint_end, ImWcharClass char_class);
|
||||
IMGUI_API void ImTextClassifierSetCharClass(ImU32* bits, unsigned int codepoint_min, unsigned int codepoint_end, ImWcharClass char_class, unsigned int c);
|
||||
IMGUI_API void ImTextClassifierSetCharClassFromStr(ImU32* bits, unsigned int codepoint_min, unsigned int codepoint_end, ImWcharClass char_class, const char* s);
|
||||
|
||||
// Helpers: File System
|
||||
#ifdef IMGUI_DISABLE_FILE_FUNCTIONS
|
||||
#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
|
||||
@@ -518,7 +526,7 @@ inline ImVec2 ImTrunc(const ImVec2& v) { return
|
||||
inline float ImFloor(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf()
|
||||
inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2(ImFloor(v.x), ImFloor(v.y)); }
|
||||
inline float ImTrunc64(float f) { return (float)(ImS64)(f); }
|
||||
inline float ImRound64(float f) { return (float)(ImS64)(f + 0.5f); }
|
||||
inline float ImRound64(float f) { return (float)(ImS64)(f + 0.5f); } // FIXME: Positive values only.
|
||||
inline int ImModPositive(int a, int b) { return (a + b) % b; }
|
||||
inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
|
||||
inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
|
||||
@@ -602,7 +610,6 @@ struct IMGUI_API ImRect
|
||||
void TranslateY(float dy) { Min.y += dy; Max.y += dy; }
|
||||
void ClipWith(const ImRect& r) { Min = ImMax(Min, r.Min); Max = ImMin(Max, r.Max); } // Simple version, may lead to an inverted rectangle, which is fine for Contains/Overlaps test but not for display.
|
||||
void ClipWithFull(const ImRect& r) { Min = ImClamp(Min, r.Min, r.Max); Max = ImClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped.
|
||||
void Floor() { Min.x = IM_TRUNC(Min.x); Min.y = IM_TRUNC(Min.y); Max.x = IM_TRUNC(Max.x); Max.y = IM_TRUNC(Max.y); }
|
||||
bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; }
|
||||
ImVec4 ToVec4() const { return ImVec4(Min.x, Min.y, Max.x, Max.y); }
|
||||
const ImVec4& AsVec4() const { return *(const ImVec4*)&Min.x; }
|
||||
@@ -636,15 +643,15 @@ typedef ImU32* ImBitArrayPtr; // Name for use in structs
|
||||
template<int BITCOUNT, int OFFSET = 0>
|
||||
struct ImBitArray
|
||||
{
|
||||
ImU32 Storage[(BITCOUNT + 31) >> 5];
|
||||
ImU32 Data[(BITCOUNT + 31) >> 5];
|
||||
ImBitArray() { ClearAllBits(); }
|
||||
void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); }
|
||||
void SetAllBits() { memset(Storage, 255, sizeof(Storage)); }
|
||||
bool TestBit(int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return IM_BITARRAY_TESTBIT(Storage, n); }
|
||||
void SetBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArraySetBit(Storage, n); }
|
||||
void ClearBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArrayClearBit(Storage, n); }
|
||||
void SetBitRange(int n, int n2) { n += OFFSET; n2 += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT && n2 > n && n2 <= BITCOUNT); ImBitArraySetBitRange(Storage, n, n2); } // Works on range [n..n2)
|
||||
bool operator[](int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return IM_BITARRAY_TESTBIT(Storage, n); }
|
||||
void ClearAllBits() { memset(Data, 0, sizeof(Data)); }
|
||||
void SetAllBits() { memset(Data, 255, sizeof(Data)); }
|
||||
bool TestBit(int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return IM_BITARRAY_TESTBIT(Data, n); }
|
||||
void SetBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArraySetBit(Data, n); }
|
||||
void ClearBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArrayClearBit(Data, n); }
|
||||
void SetBitRange(int n, int n2) { n += OFFSET; n2 += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT && n2 > n && n2 <= BITCOUNT); ImBitArraySetBitRange(Data, n, n2); } // Works on range [n..n2)
|
||||
bool operator[](int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return IM_BITARRAY_TESTBIT(Data, n); }
|
||||
};
|
||||
|
||||
// Helper: ImBitVector
|
||||
@@ -701,7 +708,7 @@ struct ImSpanAllocator
|
||||
int Offsets[CHUNKS];
|
||||
int Sizes[CHUNKS];
|
||||
|
||||
ImSpanAllocator() { memset(this, 0, sizeof(*this)); }
|
||||
ImSpanAllocator() { memset((void*)this, 0, sizeof(*this)); }
|
||||
inline void Reserve(int n, size_t sz, int a=4) { IM_ASSERT(n == CurrIdx && n < CHUNKS); CurrOff = IM_MEMALIGN(CurrOff, a); Offsets[n] = CurrOff; Sizes[n] = (int)sz; CurrIdx++; CurrOff += (int)sz; }
|
||||
inline int GetArenaSizeInBytes() { return CurrOff; }
|
||||
inline void SetArenaBasePtr(void* base_ptr) { BasePtr = (char*)base_ptr; }
|
||||
@@ -712,10 +719,10 @@ struct ImSpanAllocator
|
||||
};
|
||||
|
||||
// Helper: ImStableVector<>
|
||||
// Allocating chunks of BLOCK_SIZE items. Objects pointers are never invalidated when growing, only by clear().
|
||||
// Allocating chunks of BLOCKSIZE items. Objects pointers are never invalidated when growing, only by clear().
|
||||
// Important: does not destruct anything!
|
||||
// Implemented only the minimum set of functions we need for it.
|
||||
template<typename T, int BLOCK_SIZE>
|
||||
template<typename T, int BLOCKSIZE>
|
||||
struct ImStableVector
|
||||
{
|
||||
int Size = 0;
|
||||
@@ -729,19 +736,19 @@ struct ImStableVector
|
||||
inline void resize(int new_size) { if (new_size > Capacity) reserve(new_size); Size = new_size; }
|
||||
inline void reserve(int new_cap)
|
||||
{
|
||||
new_cap = IM_MEMALIGN(new_cap, BLOCK_SIZE);
|
||||
int old_count = Capacity / BLOCK_SIZE;
|
||||
int new_count = new_cap / BLOCK_SIZE;
|
||||
new_cap = IM_MEMALIGN(new_cap, BLOCKSIZE);
|
||||
int old_count = Capacity / BLOCKSIZE;
|
||||
int new_count = new_cap / BLOCKSIZE;
|
||||
if (new_count <= old_count)
|
||||
return;
|
||||
Blocks.resize(new_count);
|
||||
for (int n = old_count; n < new_count; n++)
|
||||
Blocks[n] = (T*)IM_ALLOC(sizeof(T) * BLOCK_SIZE);
|
||||
Blocks[n] = (T*)IM_ALLOC(sizeof(T) * BLOCKSIZE);
|
||||
Capacity = new_cap;
|
||||
}
|
||||
inline T& operator[](int i) { IM_ASSERT(i >= 0 && i < Size); return Blocks[i / BLOCK_SIZE][i % BLOCK_SIZE]; }
|
||||
inline const T& operator[](int i) const { IM_ASSERT(i >= 0 && i < Size); return Blocks[i / BLOCK_SIZE][i % BLOCK_SIZE]; }
|
||||
inline T* push_back(const T& v) { int i = Size; IM_ASSERT(i >= 0); if (Size == Capacity) reserve(Capacity + BLOCK_SIZE); void* ptr = &Blocks[i / BLOCK_SIZE][i % BLOCK_SIZE]; memcpy(ptr, &v, sizeof(v)); Size++; return (T*)ptr; }
|
||||
inline T& operator[](int i) { IM_ASSERT(i >= 0 && i < Size); return Blocks[i / BLOCKSIZE][i % BLOCKSIZE]; }
|
||||
inline const T& operator[](int i) const { IM_ASSERT(i >= 0 && i < Size); return Blocks[i / BLOCKSIZE][i % BLOCKSIZE]; }
|
||||
inline T* push_back(const T& v) { int i = Size; IM_ASSERT(i >= 0); if (Size == Capacity) reserve(Capacity + BLOCKSIZE); void* ptr = &Blocks[i / BLOCKSIZE][i % BLOCKSIZE]; memcpy(ptr, &v, sizeof(v)); Size++; return (T*)ptr; }
|
||||
};
|
||||
|
||||
// Helper: ImPool<>
|
||||
@@ -882,7 +889,7 @@ struct ImDrawDataBuilder
|
||||
ImVector<ImDrawList*>* Layers[2]; // Pointers to global layers for: regular, tooltip. LayersP[0] is owned by DrawData.
|
||||
ImVector<ImDrawList*> LayerData1;
|
||||
|
||||
ImDrawDataBuilder() { memset(this, 0, sizeof(*this)); }
|
||||
ImDrawDataBuilder() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
struct ImFontStackData
|
||||
@@ -956,7 +963,6 @@ enum ImGuiDataTypePrivate_
|
||||
enum ImGuiItemFlagsPrivate_
|
||||
{
|
||||
// Controlled by user
|
||||
ImGuiItemFlags_Disabled = 1 << 10, // false // Disable interactions (DOES NOT affect visuals. DO NOT mix direct use of this with BeginDisabled(). See BeginDisabled()/EndDisabled() for full disable feature, and github #211).
|
||||
ImGuiItemFlags_ReadOnly = 1 << 11, // false // [ALPHA] Allow hovering interactions but underlying value is not changed.
|
||||
ImGuiItemFlags_MixedValue = 1 << 12, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets)
|
||||
ImGuiItemFlags_NoWindowHoverableCheck = 1 << 13, // false // Disable hoverable check in ItemHoverable()
|
||||
@@ -1158,7 +1164,7 @@ struct IMGUI_API ImGuiComboPreviewData
|
||||
float BackupPrevLineTextBaseOffset;
|
||||
ImGuiLayoutType BackupLayout;
|
||||
|
||||
ImGuiComboPreviewData() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiComboPreviewData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Stacked storage data for BeginGroup()/EndGroup()
|
||||
@@ -1192,7 +1198,7 @@ struct IMGUI_API ImGuiMenuColumns
|
||||
ImU16 OffsetMark;
|
||||
ImU16 Widths[4]; // Width of: Icon, Label, Shortcut, Mark (accumulators for current frame)
|
||||
|
||||
ImGuiMenuColumns() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiMenuColumns() { memset((void*)this, 0, sizeof(*this)); }
|
||||
void Update(float spacing, bool window_reappearing);
|
||||
float DeclColumns(float w_icon, float w_label, float w_shortcut, float w_mark);
|
||||
void CalcNextTotalWidth(bool update_offsets);
|
||||
@@ -1204,7 +1210,7 @@ struct IMGUI_API ImGuiInputTextDeactivatedState
|
||||
ImGuiID ID; // widget id owning the text state (which just got deactivated)
|
||||
ImVector<char> TextA; // text buffer
|
||||
|
||||
ImGuiInputTextDeactivatedState() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiInputTextDeactivatedState() { memset((void*)this, 0, sizeof(*this)); }
|
||||
void ClearFreeMemory() { ID = 0; TextA.clear(); }
|
||||
};
|
||||
|
||||
@@ -1228,7 +1234,7 @@ struct IMGUI_API ImGuiInputTextState
|
||||
ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set.
|
||||
ImGuiID ID; // widget id owning the text state
|
||||
int TextLen; // UTF-8 length of the string in TextA (in bytes)
|
||||
const char* TextSrc; // == TextA.Data unless read-only, in which case == buf passed to InputText(). Field only set and valid _inside_ the call InputText() call.
|
||||
const char* TextSrc; // == TextA.Data unless read-only, in which case == buf passed to InputText(). For _ReadOnly fields, pointer will be null outside the InputText() call.
|
||||
ImVector<char> TextA; // main UTF8 buffer. TextA.Size is a buffer size! Should always be >= buf_size passed by user (and of course >= CurLenA + 1).
|
||||
ImVector<char> TextToRevertTo; // value to revert to when pressing Escape = backup of end-user buffer at the time of focus (in UTF-8, unaltered)
|
||||
ImVector<char> CallbackTextBackup; // temporary storage for callback to support automatic reconcile of undo-stack
|
||||
@@ -1262,6 +1268,7 @@ struct IMGUI_API ImGuiInputTextState
|
||||
int GetCursorPos() const;
|
||||
int GetSelectionStart() const;
|
||||
int GetSelectionEnd() const;
|
||||
void SetSelection(int start, int end);
|
||||
void SelectAll();
|
||||
|
||||
// Reload user buf (WIP #2890)
|
||||
@@ -1329,18 +1336,19 @@ struct ImGuiNextWindowData
|
||||
ImVec2 MenuBarOffsetMinVal; // (Always on) This is not exposed publicly, so we don't clear it and it doesn't have a corresponding flag (could we? for consistency?)
|
||||
ImGuiWindowRefreshFlags RefreshFlagsVal;
|
||||
|
||||
ImGuiNextWindowData() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiNextWindowData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
inline void ClearFlags() { HasFlags = ImGuiNextWindowDataFlags_None; }
|
||||
};
|
||||
|
||||
enum ImGuiNextItemDataFlags_
|
||||
{
|
||||
ImGuiNextItemDataFlags_None = 0,
|
||||
ImGuiNextItemDataFlags_HasWidth = 1 << 0,
|
||||
ImGuiNextItemDataFlags_HasOpen = 1 << 1,
|
||||
ImGuiNextItemDataFlags_HasShortcut = 1 << 2,
|
||||
ImGuiNextItemDataFlags_HasRefVal = 1 << 3,
|
||||
ImGuiNextItemDataFlags_HasStorageID = 1 << 4,
|
||||
ImGuiNextItemDataFlags_None = 0,
|
||||
ImGuiNextItemDataFlags_HasWidth = 1 << 0,
|
||||
ImGuiNextItemDataFlags_HasOpen = 1 << 1,
|
||||
ImGuiNextItemDataFlags_HasShortcut = 1 << 2,
|
||||
ImGuiNextItemDataFlags_HasRefVal = 1 << 3,
|
||||
ImGuiNextItemDataFlags_HasStorageID = 1 << 4,
|
||||
ImGuiNextItemDataFlags_HasColorMarker = 1 << 5,
|
||||
};
|
||||
|
||||
struct ImGuiNextItemData
|
||||
@@ -1358,8 +1366,9 @@ struct ImGuiNextItemData
|
||||
ImU8 OpenCond; // Set by SetNextItemOpen()
|
||||
ImGuiDataTypeStorage RefVal; // Not exposed yet, for ImGuiInputTextFlags_ParseEmptyAsRefVal
|
||||
ImGuiID StorageId; // Set by SetNextItemStorageID()
|
||||
ImU32 ColorMarker; // Set by SetNextItemColorMarker(). Not exposed yet, supported by DragScalar,SliderScalar and for ImGuiSliderFlags_ColorMarkers.
|
||||
|
||||
ImGuiNextItemData() { memset(this, 0, sizeof(*this)); SelectionUserData = -1; }
|
||||
ImGuiNextItemData() { memset((void*)this, 0, sizeof(*this)); SelectionUserData = -1; }
|
||||
inline void ClearFlags() { HasFlags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()!
|
||||
};
|
||||
|
||||
@@ -1376,7 +1385,7 @@ struct ImGuiLastItemData
|
||||
ImRect ClipRect; // Clip rectangle at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasClipRect) is set..
|
||||
ImGuiKeyChord Shortcut; // Shortcut at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasShortcut) is set..
|
||||
|
||||
ImGuiLastItemData() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiLastItemData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Store data emitted by TreeNode() for usage by TreePop()
|
||||
@@ -1409,7 +1418,7 @@ struct IMGUI_API ImGuiErrorRecoveryState
|
||||
short SizeOfBeginPopupStack;
|
||||
short SizeOfDisabledStack;
|
||||
|
||||
ImGuiErrorRecoveryState() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiErrorRecoveryState() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Data saved for each window pushed into the stack
|
||||
@@ -1470,7 +1479,7 @@ struct ImGuiPopupData
|
||||
ImVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse)
|
||||
ImVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup
|
||||
|
||||
ImGuiPopupData() { memset(this, 0, sizeof(*this)); ParentNavLayer = OpenFrameCount = -1; }
|
||||
ImGuiPopupData() { memset((void*)this, 0, sizeof(*this)); ParentNavLayer = OpenFrameCount = -1; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1548,7 +1557,7 @@ struct ImGuiInputEvent
|
||||
};
|
||||
bool AddedByTestEngine;
|
||||
|
||||
ImGuiInputEvent() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiInputEvent() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Input function taking an 'ImGuiID owner_id' argument defaults to (ImGuiKeyOwner_Any == 0) aka don't test ownership, which matches legacy behavior.
|
||||
@@ -1580,7 +1589,7 @@ struct ImGuiKeyRoutingTable
|
||||
ImVector<ImGuiKeyRoutingData> EntriesNext; // Double-buffer to avoid reallocation (could use a shared buffer)
|
||||
|
||||
ImGuiKeyRoutingTable() { Clear(); }
|
||||
void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Index); n++) Index[n] = -1; Entries.clear(); EntriesNext.clear(); }
|
||||
void Clear() { for (int n = 0; n < IM_COUNTOF(Index); n++) Index[n] = -1; Entries.clear(); EntriesNext.clear(); }
|
||||
};
|
||||
|
||||
// This extends ImGuiKeyData but only for named keys (legacy keys don't support the new features)
|
||||
@@ -1663,7 +1672,7 @@ struct ImGuiListClipperData
|
||||
int ItemsFrozen;
|
||||
ImVector<ImGuiListClipperRange> Ranges;
|
||||
|
||||
ImGuiListClipperData() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiListClipperData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
void Reset(ImGuiListClipper* clipper) { ListClipper = clipper; StepNo = ItemsFrozen = 0; Ranges.resize(0); }
|
||||
};
|
||||
|
||||
@@ -1798,7 +1807,7 @@ struct IMGUI_API ImGuiTypingSelectState
|
||||
float LastRequestTime = 0.0f;
|
||||
bool SingleCharModeLock = false; // After a certain single char repeat count we lock into SingleCharMode. Two benefits: 1) buffer never fill, 2) we can provide an immediate SingleChar mode without timer elapsing.
|
||||
|
||||
ImGuiTypingSelectState() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiTypingSelectState() { memset((void*)this, 0, sizeof(*this)); }
|
||||
void Clear() { SearchBuffer[0] = 0; SingleCharModeLock = false; } // We preserve remaining data for easier debugging
|
||||
};
|
||||
|
||||
@@ -1834,7 +1843,7 @@ struct ImGuiOldColumnData
|
||||
ImGuiOldColumnFlags Flags; // Not exposed
|
||||
ImRect ClipRect;
|
||||
|
||||
ImGuiOldColumnData() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiOldColumnData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
struct ImGuiOldColumns
|
||||
@@ -1855,7 +1864,7 @@ struct ImGuiOldColumns
|
||||
ImVector<ImGuiOldColumnData> Columns;
|
||||
ImDrawListSplitter Splitter;
|
||||
|
||||
ImGuiOldColumns() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiOldColumns() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1883,7 +1892,7 @@ struct ImGuiBoxSelectState
|
||||
ImRect BoxSelectRectPrev; // Selection rectangle in absolute coordinates (derived every frame from BoxSelectStartPosRel and MousePos)
|
||||
ImRect BoxSelectRectCurr;
|
||||
|
||||
ImGuiBoxSelectState() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiBoxSelectState() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1994,7 +2003,7 @@ struct ImGuiWindowSettings
|
||||
bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context)
|
||||
bool WantDelete; // Set to invalidate/delete the settings entry
|
||||
|
||||
ImGuiWindowSettings() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiWindowSettings() { memset((void*)this, 0, sizeof(*this)); }
|
||||
char* GetName() { return (char*)(this + 1); }
|
||||
};
|
||||
|
||||
@@ -2010,7 +2019,7 @@ struct ImGuiSettingsHandler
|
||||
void (*WriteAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* out_buf); // Write: Output every entries into 'out_buf'
|
||||
void* UserData;
|
||||
|
||||
ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiSettingsHandler() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2049,7 +2058,9 @@ struct ImGuiLocEntry
|
||||
// - See 'Demo->Configuration->Error Handling' and ImGuiIO definitions for details on error handling.
|
||||
// - Read https://github.com/ocornut/imgui/wiki/Error-Handling for details on error handling.
|
||||
#ifndef IM_ASSERT_USER_ERROR
|
||||
#define IM_ASSERT_USER_ERROR(_EXPR,_MSG) do { if (!(_EXPR) && ImGui::ErrorLog(_MSG)) { IM_ASSERT((_EXPR) && _MSG); } } while (0) // Recoverable User Error
|
||||
#define IM_ASSERT_USER_ERROR(_EXPR,_MSG) do { if (!(_EXPR)) { if (ImGui::ErrorLog(_MSG)) { IM_ASSERT((_EXPR) && _MSG); } } } while (0) // Recoverable User Error
|
||||
#define IM_ASSERT_USER_ERROR_RET(_EXPR,_MSG) do { if (!(_EXPR)) { if (ImGui::ErrorLog(_MSG)) { IM_ASSERT((_EXPR) && _MSG); } return; } } while (0) // Recoverable User Error
|
||||
#define IM_ASSERT_USER_ERROR_RETV(_EXPR,_RETV,_MSG) do { if (!(_EXPR)) { if (ImGui::ErrorLog(_MSG)) { IM_ASSERT((_EXPR) && _MSG); } return _RETV; } } while (0) // Recoverable User Error
|
||||
#endif
|
||||
|
||||
// The error callback is currently not public, as it is expected that only advanced users will rely on it.
|
||||
@@ -2079,7 +2090,8 @@ enum ImGuiDebugLogFlags_
|
||||
|
||||
ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventError | ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventSelection | ImGuiDebugLogFlags_EventIO | ImGuiDebugLogFlags_EventFont | ImGuiDebugLogFlags_EventInputRouting | ImGuiDebugLogFlags_EventDocking | ImGuiDebugLogFlags_EventViewport,
|
||||
ImGuiDebugLogFlags_OutputToTTY = 1 << 20, // Also send output to TTY
|
||||
ImGuiDebugLogFlags_OutputToTestEngine = 1 << 21, // Also send output to Test Engine
|
||||
ImGuiDebugLogFlags_OutputToDebugger = 1 << 21, // Also send output to Debugger Console [Windows only]
|
||||
ImGuiDebugLogFlags_OutputToTestEngine = 1 << 22, // Also send output to Dear ImGui Test Engine
|
||||
};
|
||||
|
||||
struct ImGuiDebugAllocEntry
|
||||
@@ -2096,7 +2108,7 @@ struct ImGuiDebugAllocInfo
|
||||
ImS16 LastEntriesIdx; // Current index in buffer
|
||||
ImGuiDebugAllocEntry LastEntriesBuf[6]; // Track last 6 frames that had allocations
|
||||
|
||||
ImGuiDebugAllocInfo() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiDebugAllocInfo() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
struct ImGuiMetricsConfig
|
||||
@@ -2125,7 +2137,7 @@ struct ImGuiStackLevelInfo
|
||||
ImS8 DataType; // ImGuiDataType
|
||||
int DescOffset; // -1 or offset into parent's ResultsPathsBuf
|
||||
|
||||
ImGuiStackLevelInfo() { memset(this, 0, sizeof(*this)); DataType = -1; DescOffset = -1; }
|
||||
ImGuiStackLevelInfo() { memset((void*)this, 0, sizeof(*this)); DataType = -1; DescOffset = -1; }
|
||||
};
|
||||
|
||||
struct ImGuiDebugItemPathQuery
|
||||
@@ -2138,7 +2150,7 @@ struct ImGuiDebugItemPathQuery
|
||||
ImGuiTextBuffer ResultsDescBuf;
|
||||
ImGuiTextBuffer ResultPathBuf;
|
||||
|
||||
ImGuiDebugItemPathQuery() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiDebugItemPathQuery() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// State for ID Stack tool queries
|
||||
@@ -2149,7 +2161,7 @@ struct ImGuiIDStackTool
|
||||
int LastActiveFrame;
|
||||
float CopyToClipboardLastTime;
|
||||
|
||||
ImGuiIDStackTool() { memset(this, 0, sizeof(*this)); LastActiveFrame = -1; OptHexEncodeNonAsciiChars = true; CopyToClipboardLastTime = -FLT_MAX; }
|
||||
ImGuiIDStackTool() { memset((void*)this, 0, sizeof(*this)); LastActiveFrame = -1; OptHexEncodeNonAsciiChars = true; CopyToClipboardLastTime = -FLT_MAX; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2167,7 +2179,7 @@ struct ImGuiContextHook
|
||||
ImGuiContextHookCallback Callback;
|
||||
void* UserData;
|
||||
|
||||
ImGuiContextHook() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiContextHook() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2340,7 +2352,7 @@ struct ImGuiContext
|
||||
ImGuiDir NavMoveDirForDebug;
|
||||
ImGuiDir NavMoveClipDir; // FIXME-NAV: Describe the purpose of this better. Might want to rename?
|
||||
ImRect NavScoringRect; // Rectangle used for scoring, in screen space. Based of window->NavRectRel[], modified for directional navigation scoring.
|
||||
ImRect NavScoringNoClipRect; // Some nav operations (such as PageUp/PageDown) enforce a region which clipper will attempt to always keep submitted
|
||||
ImRect NavScoringNoClipRect; // Some nav operations (such as PageUp/PageDown) enforce a region which clipper will attempt to always keep submitted. Unset/invalid if inverted.
|
||||
int NavScoringDebugCount; // Metrics for debugging
|
||||
int NavTabbingDir; // Generally -1 or +1, 0 when tabbing without a nav id
|
||||
int NavTabbingCounter; // >0 when counting items for tabbing
|
||||
@@ -2357,10 +2369,15 @@ struct ImGuiContext
|
||||
bool NavJustMovedToIsTabbing; // Copy of ImGuiNavMoveFlags_IsTabbing. Maybe we should store whole flags.
|
||||
bool NavJustMovedToHasSelectionData; // Copy of move result's ItemFlags & ImGuiItemFlags_HasSelectionUserData). Maybe we should just store ImGuiNavItemData.
|
||||
|
||||
// Navigation: Windowing (Ctrl+Tab for list, or Menu button + keys or directional pads to move/resize)
|
||||
// Navigation: extra config options (will be made public eventually)
|
||||
// - Tabbing (Tab, Shift+Tab) and Windowing (Ctrl+Tab, Ctrl+Shift+Tab) are enabled REGARDLESS of ImGuiConfigFlags_NavEnableKeyboard being set.
|
||||
// - Ctrl+Tab is reconfigurable because it is the only shortcut that may be polled when no window are focused. It also doesn't work e.g. Web platforms.
|
||||
bool ConfigNavEnableTabbing; // = true. Enable tabbing (Tab, Shift+Tab). PLEASE LET ME KNOW IF YOU USE THIS.
|
||||
bool ConfigNavWindowingWithGamepad; // = true. Enable Ctrl+Tab by holding ImGuiKey_GamepadFaceLeft (== ImGuiKey_NavGamepadMenu). When false, the button may still be used to toggle Menu layer.
|
||||
ImGuiKeyChord ConfigNavWindowingKeyNext; // = ImGuiMod_Ctrl | ImGuiKey_Tab (or ImGuiMod_Super | ImGuiKey_Tab on OS X). For reconfiguration (see #4828)
|
||||
ImGuiKeyChord ConfigNavWindowingKeyNext; // = ImGuiMod_Ctrl | ImGuiKey_Tab (or ImGuiMod_Super | ImGuiKey_Tab on OS X). Set to 0 to disable. For reconfiguration (see #4828)
|
||||
ImGuiKeyChord ConfigNavWindowingKeyPrev; // = ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab (or ImGuiMod_Super | ImGuiMod_Shift | ImGuiKey_Tab on OS X)
|
||||
|
||||
// Navigation: Windowing (Ctrl+Tab for list, or Menu button + keys or directional pads to move/resize)
|
||||
ImGuiWindow* NavWindowingTarget; // Target window when doing Ctrl+Tab (or Pad Menu + FocusPrev/Next), this window is temporarily displayed top-most!
|
||||
ImGuiWindow* NavWindowingTargetAnim; // Record of last valid NavWindowingTarget until DimBgRatio and NavWindowingHighlightAlpha becomes 0.0f, so the fade-out can stay on it.
|
||||
ImGuiWindow* NavWindowingListWindow; // Internal window actually listing the Ctrl+Tab contents
|
||||
@@ -2562,6 +2579,8 @@ struct ImGuiContext
|
||||
// [SECTION] ImGuiWindowTempData, ImGuiWindow
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define IMGUI_WINDOW_HARD_MIN_SIZE 4.0f
|
||||
|
||||
// Transient per-window data, reset at the beginning of the frame. This used to be called ImGuiDrawContext, hence the DC variable name in ImGuiWindow.
|
||||
// (That's theory, in practice the delimitation between ImGuiWindow and ImGuiWindowTempData is quite tenuous and could be reconsidered..)
|
||||
// (This doesn't need a constructor because we zero-clear it as part of ImGuiWindow and all frame-temporary data are setup on Begin)
|
||||
@@ -2612,6 +2631,7 @@ struct IMGUI_API ImGuiWindowTempData
|
||||
// Local parameters stacks
|
||||
// We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings.
|
||||
float ItemWidth; // Current item width (>0.0: width in pixels, <0.0: align xx pixels to the right of window).
|
||||
float ItemWidthDefault;
|
||||
float TextWrapPos; // Current text wrap pos.
|
||||
ImVector<float> ItemWidthStack; // Store item widths to restore (attention: .back() is not == ItemWidth)
|
||||
ImVector<float> TextWrapPosStack; // Store text wrap pos to restore (attention: .back() is not == TextWrapPos)
|
||||
@@ -2702,7 +2722,6 @@ struct IMGUI_API ImGuiWindow
|
||||
|
||||
int LastFrameActive; // Last frame number the window was Active.
|
||||
float LastTimeActive; // Last timestamp the window was Active (using float as we don't need high precision there)
|
||||
float ItemWidthDefault;
|
||||
ImGuiStorage StateStorage;
|
||||
ImVector<ImGuiOldColumns> ColumnsStorage;
|
||||
float FontWindowScale; // User scale multiplier per-window, via SetWindowFontScale()
|
||||
@@ -2778,7 +2797,7 @@ struct ImGuiTabItem
|
||||
ImGuiTabItemFlags Flags;
|
||||
int LastFrameVisible;
|
||||
int LastFrameSelected; // This allows us to infer an ordered list of the last activated tabs with little maintenance
|
||||
float Offset; // Position relative to beginning of tab
|
||||
float Offset; // Position relative to beginning of tab bar
|
||||
float Width; // Width currently displayed
|
||||
float ContentWidth; // Width of label + padding, stored during BeginTabItem() call (misnamed as "Content" would normally imply width of label only)
|
||||
float RequestedWidth; // Width optionally requested by caller, -1.0f is unused
|
||||
@@ -2787,7 +2806,7 @@ struct ImGuiTabItem
|
||||
ImS16 IndexDuringLayout; // Index only used during TabBarLayout(). Tabs gets reordered so 'Tabs[n].IndexDuringLayout == n' but may mismatch during additions.
|
||||
bool WantClose; // Marked as closed by SetTabItemClosed()
|
||||
|
||||
ImGuiTabItem() { memset(this, 0, sizeof(*this)); LastFrameVisible = LastFrameSelected = -1; RequestedWidth = -1.0f; NameOffset = -1; BeginOrder = IndexDuringLayout = -1; }
|
||||
ImGuiTabItem() { memset((void*)this, 0, sizeof(*this)); LastFrameVisible = LastFrameSelected = -1; RequestedWidth = -1.0f; NameOffset = -1; BeginOrder = IndexDuringLayout = -1; }
|
||||
};
|
||||
|
||||
// Storage for a tab bar (sizeof() 160 bytes)
|
||||
@@ -2799,6 +2818,7 @@ struct IMGUI_API ImGuiTabBar
|
||||
ImGuiID ID; // Zero for tab-bars used by docking
|
||||
ImGuiID SelectedTabId; // Selected tab/window
|
||||
ImGuiID NextSelectedTabId; // Next selected tab/window. Will also trigger a scrolling animation
|
||||
ImGuiID NextScrollToTabId;
|
||||
ImGuiID VisibleTabId; // Can occasionally be != SelectedTabId (e.g. when previewing contents for Ctrl+Tab preview)
|
||||
int CurrFrameVisible;
|
||||
int PrevFrameVisible;
|
||||
@@ -2891,7 +2911,7 @@ struct ImGuiTableColumn
|
||||
|
||||
ImGuiTableColumn()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
StretchWeight = WidthRequest = -1.0f;
|
||||
NameOffset = -1;
|
||||
DisplayOrder = IndexWithinEnabledSet = -1;
|
||||
@@ -3052,7 +3072,7 @@ struct IMGUI_API ImGuiTable
|
||||
bool MemoryCompacted;
|
||||
bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite InnerWindow->SkipItem on a per-column basis
|
||||
|
||||
ImGuiTable() { memset(this, 0, sizeof(*this)); LastFrameActive = -1; }
|
||||
ImGuiTable() { memset((void*)this, 0, sizeof(*this)); LastFrameActive = -1; }
|
||||
~ImGuiTable() { IM_FREE(RawData); }
|
||||
};
|
||||
|
||||
@@ -3081,7 +3101,7 @@ struct IMGUI_API ImGuiTableTempData
|
||||
float HostBackupItemWidth; // Backup of OuterWindow->DC.ItemWidth at the end of BeginTable()
|
||||
int HostBackupItemWidthStackSize;//Backup of OuterWindow->DC.ItemWidthStack.Size at the end of BeginTable()
|
||||
|
||||
ImGuiTableTempData() { memset(this, 0, sizeof(*this)); LastTimeActive = -1.0f; }
|
||||
ImGuiTableTempData() { memset((void*)this, 0, sizeof(*this)); LastTimeActive = -1.0f; }
|
||||
};
|
||||
|
||||
// sizeof() ~ 16
|
||||
@@ -3118,7 +3138,7 @@ struct ImGuiTableSettings
|
||||
ImGuiTableColumnIdx ColumnsCountMax; // Maximum number of columns this settings instance can store, we can recycle a settings instance with lower number of columns but not higher
|
||||
bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context)
|
||||
|
||||
ImGuiTableSettings() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiTableSettings() { memset((void*)this, 0, sizeof(*this)); }
|
||||
ImGuiTableColumnSettings* GetColumnSettings() { return (ImGuiTableColumnSettings*)(this + 1); }
|
||||
};
|
||||
|
||||
@@ -3136,6 +3156,7 @@ namespace ImGui
|
||||
// - You are calling ImGui functions after ImGui::EndFrame()/ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal.
|
||||
IMGUI_API ImGuiIO& GetIO(ImGuiContext* ctx);
|
||||
IMGUI_API ImGuiPlatformIO& GetPlatformIO(ImGuiContext* ctx);
|
||||
inline float GetScale() { ImGuiContext& g = *GImGui; return g.Style._MainScale; } // FIXME-DPI: I don't want to formalize this just yet. Because reasons. Please don't use.
|
||||
inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; }
|
||||
inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; }
|
||||
IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id);
|
||||
@@ -3194,6 +3215,12 @@ namespace ImGui
|
||||
IMGUI_API void Initialize();
|
||||
IMGUI_API void Shutdown(); // Since 1.60 this is a _private_ function. You can call DestroyContext() to destroy the context created by CreateContext().
|
||||
|
||||
// Context name & generic context hooks
|
||||
IMGUI_API void SetContextName(ImGuiContext* ctx, const char* name);
|
||||
IMGUI_API ImGuiID AddContextHook(ImGuiContext* ctx, const ImGuiContextHook* hook);
|
||||
IMGUI_API void RemoveContextHook(ImGuiContext* ctx, ImGuiID hook_to_remove);
|
||||
IMGUI_API void CallContextHooks(ImGuiContext* ctx, ImGuiContextHookType type);
|
||||
|
||||
// NewFrame
|
||||
IMGUI_API void UpdateInputEvents(bool trickle_fast_inputs);
|
||||
IMGUI_API void UpdateHoveredWindowAndCaptureFlags(const ImVec2& mouse_pos);
|
||||
@@ -3203,12 +3230,8 @@ namespace ImGui
|
||||
IMGUI_API void UpdateMouseMovingWindowNewFrame();
|
||||
IMGUI_API void UpdateMouseMovingWindowEndFrame();
|
||||
|
||||
// Generic context hooks
|
||||
IMGUI_API ImGuiID AddContextHook(ImGuiContext* context, const ImGuiContextHook* hook);
|
||||
IMGUI_API void RemoveContextHook(ImGuiContext* context, ImGuiID hook_to_remove);
|
||||
IMGUI_API void CallContextHooks(ImGuiContext* context, ImGuiContextHookType type);
|
||||
|
||||
// Viewports
|
||||
inline ImGuiViewport* GetWindowViewport() { return GetMainViewport(); } // For code consistency. This is public API in docking branch.
|
||||
IMGUI_API void ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale);
|
||||
IMGUI_API void SetWindowViewport(ImGuiWindow* window, ImGuiViewportP* viewport);
|
||||
|
||||
@@ -3246,7 +3269,6 @@ namespace ImGui
|
||||
|
||||
// Basic Accessors
|
||||
inline ImGuiItemStatusFlags GetItemStatusFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.StatusFlags; }
|
||||
inline ImGuiItemFlags GetItemFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.ItemFlags; }
|
||||
inline ImGuiID GetActiveID() { ImGuiContext& g = *GImGui; return g.ActiveId; }
|
||||
inline ImGuiID GetFocusID() { ImGuiContext& g = *GImGui; return g.NavId; }
|
||||
IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window);
|
||||
@@ -3302,6 +3324,7 @@ namespace ImGui
|
||||
IMGUI_API ImGuiWindow* FindBlockingModal(ImGuiWindow* window);
|
||||
IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window);
|
||||
IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy);
|
||||
IMGUI_API ImGuiMouseButton GetMouseButtonFromPopupFlags(ImGuiPopupFlags flags);
|
||||
|
||||
// Tooltips
|
||||
IMGUI_API bool BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags extra_window_flags);
|
||||
@@ -3509,6 +3532,7 @@ namespace ImGui
|
||||
IMGUI_API void TableMergeDrawChannels(ImGuiTable* table);
|
||||
inline ImGuiTableInstanceData* TableGetInstanceData(ImGuiTable* table, int instance_no) { if (instance_no == 0) return &table->InstanceDataFirst; return &table->InstanceDataExtra[instance_no - 1]; }
|
||||
inline ImGuiID TableGetInstanceID(ImGuiTable* table, int instance_no) { return TableGetInstanceData(table, instance_no)->TableInstanceID; }
|
||||
IMGUI_API void TableFixDisplayOrder(ImGuiTable* table);
|
||||
IMGUI_API void TableSortSpecsSanitize(ImGuiTable* table);
|
||||
IMGUI_API void TableSortSpecsBuild(ImGuiTable* table);
|
||||
IMGUI_API ImGuiSortDirection TableGetColumnNextSortDirection(ImGuiTableColumn* column);
|
||||
@@ -3524,6 +3548,7 @@ namespace ImGui
|
||||
IMGUI_API float TableCalcMaxColumnWidth(const ImGuiTable* table, int column_n);
|
||||
IMGUI_API void TableSetColumnWidthAutoSingle(ImGuiTable* table, int column_n);
|
||||
IMGUI_API void TableSetColumnWidthAutoAll(ImGuiTable* table);
|
||||
IMGUI_API void TableSetColumnDisplayOrder(ImGuiTable* table, int column_n, int dst_order);
|
||||
IMGUI_API void TableRemove(ImGuiTable* table);
|
||||
IMGUI_API void TableGcCompactTransientBuffers(ImGuiTable* table);
|
||||
IMGUI_API void TableGcCompactTransientBuffers(ImGuiTableTempData* table);
|
||||
@@ -3572,6 +3597,7 @@ namespace ImGui
|
||||
IMGUI_API void RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float ellipsis_max_x, const char* text, const char* text_end, const ImVec2* text_size_if_known);
|
||||
IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool borders = true, float rounding = 0.0f);
|
||||
IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f);
|
||||
IMGUI_API void RenderColorComponentMarker(const ImRect& bb, ImU32 col, float rounding);
|
||||
IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, ImDrawFlags flags = 0);
|
||||
IMGUI_API void RenderNavCursor(const ImRect& bb, ImGuiID id, ImGuiNavRenderCursorFlags flags = ImGuiNavRenderCursorFlags_None); // Navigation highlight
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
@@ -3585,8 +3611,9 @@ namespace ImGui
|
||||
IMGUI_API void RenderBullet(ImDrawList* draw_list, ImVec2 pos, ImU32 col);
|
||||
IMGUI_API void RenderCheckMark(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz);
|
||||
IMGUI_API void RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col);
|
||||
IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding);
|
||||
IMGUI_API void RenderRectFilledInRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float fill_x0, float fill_x1, float rounding);
|
||||
IMGUI_API void RenderRectFilledWithHole(ImDrawList* draw_list, const ImRect& outer, const ImRect& inner, ImU32 col, float rounding);
|
||||
IMGUI_API ImDrawFlags CalcRoundingFlagsForRectInRect(const ImRect& r_in, const ImRect& r_outer, float threshold);
|
||||
|
||||
// Widgets: Text
|
||||
IMGUI_API void TextEx(const char* text, const char* text_end = NULL, ImGuiTextFlags flags = 0);
|
||||
@@ -3651,7 +3678,7 @@ namespace ImGui
|
||||
IMGUI_API void InputTextDeactivateHook(ImGuiID id);
|
||||
IMGUI_API bool TempInputText(const ImRect& bb, ImGuiID id, const char* label, char* buf, int buf_size, ImGuiInputTextFlags flags);
|
||||
IMGUI_API bool TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format, const void* p_clamp_min = NULL, const void* p_clamp_max = NULL);
|
||||
inline bool TempInputIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputId == id); }
|
||||
inline bool TempInputIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return g.ActiveId == id && g.TempInputId == id; }
|
||||
inline ImGuiInputTextState* GetInputTextState(ImGuiID id) { ImGuiContext& g = *GImGui; return (id != 0 && g.InputTextState.ID == id) ? &g.InputTextState : NULL; } // Get input text state if active
|
||||
IMGUI_API void SetNextItemRefVal(ImGuiDataType data_type, void* p_data);
|
||||
inline bool IsItemActiveAsInputText() { ImGuiContext& g = *GImGui; return g.ActiveId != 0 && g.ActiveId == g.LastItemData.ID && g.InputTextState.ID == g.LastItemData.ID; } // This may be useful to apply workaround that a based on distinguish whenever an item is active as a text input field.
|
||||
@@ -3660,6 +3687,7 @@ namespace ImGui
|
||||
IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags);
|
||||
IMGUI_API void ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags);
|
||||
IMGUI_API void ColorPickerOptionsPopup(const float* ref_col, ImGuiColorEditFlags flags);
|
||||
inline void SetNextItemColorMarker(ImU32 col) { ImGuiContext& g = *GImGui; g.NextItemData.HasFlags |= ImGuiNextItemDataFlags_HasColorMarker; g.NextItemData.ColorMarker = col; }
|
||||
|
||||
// Plot
|
||||
IMGUI_API int PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, const ImVec2& size_arg);
|
||||
@@ -3697,6 +3725,7 @@ namespace ImGui
|
||||
IMGUI_API bool DebugBreakButton(const char* label, const char* description_of_location);
|
||||
IMGUI_API void DebugBreakButtonTooltip(bool keyboard_only, const char* description_of_location);
|
||||
IMGUI_API void ShowFontAtlas(ImFontAtlas* atlas);
|
||||
IMGUI_API ImU64 DebugTextureIDToU64(ImTextureID tex_id);
|
||||
IMGUI_API void DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* data_id, const void* data_id_end);
|
||||
IMGUI_API void DebugNodeColumns(ImGuiOldColumns* columns);
|
||||
IMGUI_API void DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, const ImDrawList* draw_list, const char* label);
|
||||
@@ -3760,14 +3789,14 @@ struct ImFontLoader
|
||||
// FIXME: At this point the two other types of buffers may be managed by core to be consistent?
|
||||
size_t FontBakedSrcLoaderDataSize;
|
||||
|
||||
ImFontLoader() { memset(this, 0, sizeof(*this)); }
|
||||
ImFontLoader() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
#ifdef IMGUI_ENABLE_STB_TRUETYPE
|
||||
IMGUI_API const ImFontLoader* ImFontAtlasGetFontLoaderForStbTruetype();
|
||||
#endif
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
typedef ImFontLoader ImFontBuilderIO; // [renamed/changed in 1.92] The types are not actually compatible but we provide this as a compile-time error report helper.
|
||||
typedef ImFontLoader ImFontBuilderIO; // [renamed/changed in 1.92.0] The types are not actually compatible but we provide this as a compile-time error report helper.
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -3857,7 +3886,7 @@ struct ImFontAtlasBuilder
|
||||
ImFontAtlasRectId PackIdMouseCursors; // White pixel + mouse cursors. Also happen to be fallback in case of packing failure.
|
||||
ImFontAtlasRectId PackIdLinesTexData;
|
||||
|
||||
ImFontAtlasBuilder() { memset(this, 0, sizeof(*this)); FrameCount = -1; RectsIndexFreeListStart = -1; PackIdMouseCursors = PackIdLinesTexData = -1; }
|
||||
ImFontAtlasBuilder() { memset((void*)this, 0, sizeof(*this)); FrameCount = -1; RectsIndexFreeListStart = -1; PackIdMouseCursors = PackIdLinesTexData = -1; }
|
||||
};
|
||||
|
||||
IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas);
|
||||
@@ -3886,6 +3915,7 @@ IMGUI_API void ImFontAtlasFontSourceAddToFont(ImFontAtlas* atlas, I
|
||||
IMGUI_API void ImFontAtlasFontDestroySourceData(ImFontAtlas* atlas, ImFontConfig* src);
|
||||
IMGUI_API bool ImFontAtlasFontInitOutput(ImFontAtlas* atlas, ImFont* font); // Using FontDestroyOutput/FontInitOutput sequence useful notably if font loader params have changed
|
||||
IMGUI_API void ImFontAtlasFontDestroyOutput(ImFontAtlas* atlas, ImFont* font);
|
||||
IMGUI_API void ImFontAtlasFontRebuildOutput(ImFontAtlas* atlas, ImFont* font);
|
||||
IMGUI_API void ImFontAtlasFontDiscardBakes(ImFontAtlas* atlas, ImFont* font, int unused_frames);
|
||||
|
||||
IMGUI_API ImGuiID ImFontAtlasBakedGetId(ImGuiID font_id, float baked_size, float rasterizer_density);
|
||||
|
||||
Vendored
+315
-243
File diff suppressed because it is too large
Load Diff
Vendored
+208
-146
File diff suppressed because it is too large
Load Diff
Vendored
+498
-110
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.5
|
||||
// dear imgui, v1.92.6
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
@@ -17,10 +17,11 @@ Index of this file:
|
||||
// [SECTION] ImFontAtlas: backend for stb_truetype
|
||||
// [SECTION] ImFontAtlas: glyph ranges helpers
|
||||
// [SECTION] ImFontGlyphRangesBuilder
|
||||
// [SECTION] ImFont
|
||||
// [SECTION] ImFontBaked, ImFont
|
||||
// [SECTION] ImGui Internal Render Helpers
|
||||
// [SECTION] Decompression code
|
||||
// [SECTION] Default font data (ProggyClean.ttf)
|
||||
// [SECTION] Default font data (ProggyForever.ttf)
|
||||
|
||||
*/
|
||||
|
||||
@@ -81,6 +82,7 @@ Index of this file:
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion" // warning: conversion to 'xxxx' from 'xxxx' may change the sign of the result
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -103,6 +105,7 @@ namespace IMGUI_STB_NAMESPACE
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4456) // declaration of 'xx' hides previous local declaration
|
||||
#pragma warning (disable: 6011) // (stb_rectpack) Dereferencing NULL pointer 'cur->next'.
|
||||
#pragma warning (disable: 5262) // (stb_truetype) implicit fall-through occurs here; are you missing a break statement?
|
||||
#pragma warning (disable: 6385) // (stb_truetype) Reading invalid data from 'buffer': the readable size is '_Old_3`kernel_width' bytes, but '3' bytes may be read.
|
||||
#pragma warning (disable: 28182) // (stb_rectpack) Dereferencing NULL pointer. 'cur' contains the same NULL value as 'cur->next' did.
|
||||
#endif
|
||||
@@ -389,11 +392,11 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
|
||||
|
||||
ImDrawListSharedData::ImDrawListSharedData()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
InitialFringeScale = 1.0f;
|
||||
for (int i = 0; i < IM_ARRAYSIZE(ArcFastVtx); i++)
|
||||
for (int i = 0; i < IM_COUNTOF(ArcFastVtx); i++)
|
||||
{
|
||||
const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(ArcFastVtx);
|
||||
const float a = ((float)i * 2 * IM_PI) / (float)IM_COUNTOF(ArcFastVtx);
|
||||
ArcFastVtx[i] = ImVec2(ImCos(a), ImSin(a));
|
||||
}
|
||||
ArcFastRadiusCutoff = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(IM_DRAWLIST_ARCFAST_SAMPLE_MAX, CircleSegmentMaxError);
|
||||
@@ -411,7 +414,7 @@ void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error)
|
||||
|
||||
IM_ASSERT(max_error > 0.0f);
|
||||
CircleSegmentMaxError = max_error;
|
||||
for (int i = 0; i < IM_ARRAYSIZE(CircleSegmentCounts); i++)
|
||||
for (int i = 0; i < IM_COUNTOF(CircleSegmentCounts); i++)
|
||||
{
|
||||
const float radius = (float)i;
|
||||
CircleSegmentCounts[i] = (ImU8)((i > 0) ? IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleSegmentMaxError) : IM_DRAWLIST_ARCFAST_SAMPLE_MAX);
|
||||
@@ -421,7 +424,7 @@ void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error)
|
||||
|
||||
ImDrawList::ImDrawList(ImDrawListSharedData* shared_data)
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
_SetDrawListSharedData(shared_data);
|
||||
}
|
||||
|
||||
@@ -444,10 +447,13 @@ void ImDrawList::_SetDrawListSharedData(ImDrawListSharedData* data)
|
||||
// In the majority of cases, you would want to call PushClipRect() and PushTexture() after this.
|
||||
void ImDrawList::_ResetForNewFrame()
|
||||
{
|
||||
// Verify that the ImDrawCmd fields we want to memcmp() are contiguous in memory.
|
||||
// Verify that the ImDrawCmd fields we want to memcmp() are contiguous in memory to match ImDrawCmdHeader.
|
||||
IM_STATIC_ASSERT(offsetof(ImDrawCmd, ClipRect) == 0);
|
||||
IM_STATIC_ASSERT(offsetof(ImDrawCmd, TexRef) == sizeof(ImVec4));
|
||||
IM_STATIC_ASSERT(offsetof(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureRef));
|
||||
IM_STATIC_ASSERT(offsetof(ImDrawCmd, ClipRect) == offsetof(ImDrawCmdHeader, ClipRect));
|
||||
IM_STATIC_ASSERT(offsetof(ImDrawCmd, TexRef) == offsetof(ImDrawCmdHeader, TexRef));
|
||||
IM_STATIC_ASSERT(offsetof(ImDrawCmd, VtxOffset) == offsetof(ImDrawCmdHeader, VtxOffset));
|
||||
if (_Splitter._Count > 1)
|
||||
_Splitter.Merge(this);
|
||||
|
||||
@@ -643,7 +649,7 @@ int ImDrawList::_CalcCircleAutoSegmentCount(float radius) const
|
||||
{
|
||||
// Automatic segment count
|
||||
const int radius_idx = (int)(radius + 0.999999f); // ceil to never reduce accuracy
|
||||
if (radius_idx >= 0 && radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts))
|
||||
if (radius_idx >= 0 && radius_idx < IM_COUNTOF(_Data->CircleSegmentCounts))
|
||||
return _Data->CircleSegmentCounts[radius_idx]; // Use cached value
|
||||
else
|
||||
return IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError);
|
||||
@@ -2411,13 +2417,15 @@ void ImGui::ShadeVertsTransformPos(ImDrawList* draw_list, int vert_start_idx, in
|
||||
// FIXME-NEWATLAS: Oversample specification could be more dynamic. For now, favoring automatic selection.
|
||||
ImFontConfig::ImFontConfig()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
FontDataOwnedByAtlas = true;
|
||||
OversampleH = 0; // Auto == 1 or 2 depending on size
|
||||
OversampleV = 0; // Auto == 1
|
||||
ExtraSizeScale = 1.0f;
|
||||
GlyphMaxAdvanceX = FLT_MAX;
|
||||
RasterizerMultiply = 1.0f;
|
||||
RasterizerDensity = 1.0f;
|
||||
LineHeight = 1.0f;
|
||||
EllipsisChar = 0;
|
||||
}
|
||||
|
||||
@@ -2513,6 +2521,8 @@ void ImTextureData::DestroyPixels()
|
||||
//-----------------------------------------------------------------------------
|
||||
// - ImFontAtlas::AddFont()
|
||||
// - ImFontAtlas::AddFontDefault()
|
||||
// - ImFontAtlas::AddFontDefaultBitmap()
|
||||
// - ImFontAtlas::AddFontDefaultVector()
|
||||
// - ImFontAtlas::AddFontFromFileTTF()
|
||||
// - ImFontAtlas::AddFontFromMemoryTTF()
|
||||
// - ImFontAtlas::AddFontFromMemoryCompressedTTF()
|
||||
@@ -2632,7 +2642,7 @@ static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_COUNT][3
|
||||
|
||||
ImFontAtlas::ImFontAtlas()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
TexDesiredFormat = ImTextureFormat_RGBA32;
|
||||
TexGlyphPadding = 1;
|
||||
TexMinWidth = 512;
|
||||
@@ -3028,6 +3038,7 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg_in)
|
||||
ImFontAtlasBuildInit(this);
|
||||
|
||||
// Create new font
|
||||
const bool is_first_font = (Fonts.Size == 0);
|
||||
ImFont* font;
|
||||
if (!font_cfg_in->MergeMode)
|
||||
{
|
||||
@@ -3036,12 +3047,14 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg_in)
|
||||
font->Flags = font_cfg_in->Flags;
|
||||
font->LegacySize = font_cfg_in->SizePixels;
|
||||
font->CurrentRasterizerDensity = font_cfg_in->RasterizerDensity;
|
||||
font->LineHeight = font_cfg_in->LineHeight;
|
||||
Fonts.push_back(font);
|
||||
}
|
||||
else
|
||||
{
|
||||
IM_ASSERT(Fonts.Size > 0 && "Cannot use MergeMode for the first font"); // When using MergeMode make sure that a font has already been added before. You can use ImGui::GetIO().Fonts->AddFontDefault() to add the default imgui font.
|
||||
IM_ASSERT(Fonts.Size > 0 && "Cannot use MergeMode for the first font"); // When using MergeMode make sure that a font has already been added before.
|
||||
font = font_cfg_in->DstFont ? font_cfg_in->DstFont : Fonts.back();
|
||||
ImFontAtlasFontDiscardBakes(this, font, 0); // Need to discard bakes if the font was already used, because baked->FontLoaderDatas[] will change size. (#9162)
|
||||
}
|
||||
|
||||
// Add to list
|
||||
@@ -3052,12 +3065,6 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg_in)
|
||||
font->Sources.push_back(font_cfg);
|
||||
ImFontAtlasBuildUpdatePointers(this); // Pointers to Sources are otherwise dangling after we called Sources.push_back().
|
||||
|
||||
if (font_cfg->FontDataOwnedByAtlas == false)
|
||||
{
|
||||
font_cfg->FontDataOwnedByAtlas = true;
|
||||
font_cfg->FontData = ImMemdup(font_cfg->FontData, (size_t)font_cfg->FontDataSize);
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
// We don't round cfg.SizePixels yet as relative size of merged fonts are used afterwards.
|
||||
if (font_cfg->GlyphExcludeRanges != NULL)
|
||||
@@ -3090,6 +3097,8 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg_in)
|
||||
}
|
||||
ImFontAtlasFontSourceAddToFont(this, font, font_cfg);
|
||||
|
||||
if (is_first_font)
|
||||
ImFontAtlasBuildNotifySetFont(this, NULL, font);
|
||||
return font;
|
||||
}
|
||||
|
||||
@@ -3108,32 +3117,72 @@ static void Decode85(const unsigned char* src, unsigned char* dst)
|
||||
}
|
||||
}
|
||||
#ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
static const char* GetDefaultCompressedFontDataTTF(int* out_size);
|
||||
static const char* GetDefaultCompressedFontDataProggyClean(int* out_size);
|
||||
static const char* GetDefaultCompressedFontDataProggyForever(int* out_size);
|
||||
#endif
|
||||
|
||||
// Load embedded ProggyClean.ttf at size 13, disable oversampling
|
||||
// If you want a similar font which may be better scaled, consider using ProggyVector from the same author!
|
||||
ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template)
|
||||
// This duplicates some of the logic in UpdateFontsNewFrame() which is a bit chicken-and-eggy/tricky to extract due to variety of codepaths and possible initialization ordering.
|
||||
static float GetExpectedContextFontSize(ImGuiContext* ctx)
|
||||
{
|
||||
return ((ctx->Style.FontSizeBase > 0.0f) ? ctx->Style.FontSizeBase : 13.0f) * ctx->Style.FontScaleMain * ctx->Style.FontScaleDpi;
|
||||
}
|
||||
|
||||
// Legacy function with heuristic to select Pixel or Vector font.
|
||||
// The selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a small threshold at the time of adding the default font.
|
||||
// Prefer calling AddFontDefaultVector() or AddFontDefaultBitmap() based on your own logic.
|
||||
ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg)
|
||||
{
|
||||
if (OwnerContext == NULL || GetExpectedContextFontSize(OwnerContext) >= 15.0f)
|
||||
return AddFontDefaultVector(font_cfg);
|
||||
else
|
||||
return AddFontDefaultBitmap(font_cfg);
|
||||
}
|
||||
|
||||
// Load embedded ProggyClean.ttf. Default size 13, disable oversampling.
|
||||
// If you want a similar font which may be better scaled, consider using AddFontDefaultVector().
|
||||
ImFont* ImFontAtlas::AddFontDefaultBitmap(const ImFontConfig* font_cfg_template)
|
||||
{
|
||||
#ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig();
|
||||
if (!font_cfg_template)
|
||||
{
|
||||
font_cfg.OversampleH = font_cfg.OversampleV = 1;
|
||||
font_cfg.PixelSnapH = true;
|
||||
}
|
||||
font_cfg.PixelSnapH = true; // Prevents sub-integer scaling factors at lower-level layers.
|
||||
if (font_cfg.SizePixels <= 0.0f)
|
||||
font_cfg.SizePixels = 13.0f * 1.0f;
|
||||
font_cfg.SizePixels = 13.0f; // This only serves (1) as a reference for GlyphOffset.y setting and (2) as a default for pre-1.92 backend.
|
||||
if (font_cfg.Name[0] == '\0')
|
||||
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "ProggyClean.ttf");
|
||||
ImFormatString(font_cfg.Name, IM_COUNTOF(font_cfg.Name), "ProggyClean.ttf");
|
||||
font_cfg.EllipsisChar = (ImWchar)0x0085;
|
||||
font_cfg.GlyphOffset.y += 1.0f * IM_TRUNC(font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units
|
||||
font_cfg.GlyphOffset.y += 1.0f * (font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units
|
||||
|
||||
int ttf_compressed_size = 0;
|
||||
const char* ttf_compressed = GetDefaultCompressedFontDataTTF(&ttf_compressed_size);
|
||||
const char* ttf_compressed = GetDefaultCompressedFontDataProggyClean(&ttf_compressed_size);
|
||||
return AddFontFromMemoryCompressedTTF(ttf_compressed, ttf_compressed_size, font_cfg.SizePixels, &font_cfg);
|
||||
#else
|
||||
IM_ASSERT(0 && "AddFontDefault() disabled in this build.");
|
||||
IM_ASSERT(0 && "Function is disabled in this build.");
|
||||
IM_UNUSED(font_cfg_template);
|
||||
return NULL;
|
||||
#endif // #ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
}
|
||||
|
||||
// Load a minimal version of ProggyForever, designed to match our good old ProggyClean, but nicely scalable.
|
||||
// (See build script in https://github.com/ocornut/proggyforever for details)
|
||||
ImFont* ImFontAtlas::AddFontDefaultVector(const ImFontConfig* font_cfg_template)
|
||||
{
|
||||
#ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig();
|
||||
if (!font_cfg_template)
|
||||
font_cfg.PixelSnapH = true; // Precisely match ProggyClean, but prevents sub-integer scaling factors at lower-level layers.
|
||||
if (font_cfg.SizePixels <= 0.0f)
|
||||
font_cfg.SizePixels = 13.0f;
|
||||
if (font_cfg.Name[0] == '\0')
|
||||
ImFormatString(font_cfg.Name, IM_COUNTOF(font_cfg.Name), "ProggyForever.ttf");
|
||||
font_cfg.ExtraSizeScale *= 1.015f; // Match ProggyClean
|
||||
font_cfg.GlyphOffset.y += 0.5f * (font_cfg.SizePixels / 16.0f); // Closer match ProggyClean + avoid descenders going too high (with current code).
|
||||
|
||||
int ttf_compressed_size = 0;
|
||||
const char* ttf_compressed = GetDefaultCompressedFontDataProggyForever(&ttf_compressed_size);
|
||||
return AddFontFromMemoryCompressedTTF(ttf_compressed, ttf_compressed_size, font_cfg.SizePixels, &font_cfg);
|
||||
#else
|
||||
IM_ASSERT(0 && "Function is disabled in this build.");
|
||||
IM_UNUSED(font_cfg_template);
|
||||
return NULL;
|
||||
#endif // #ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
@@ -3159,7 +3208,7 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels,
|
||||
// Store a short copy of filename into into the font name for convenience
|
||||
const char* p;
|
||||
for (p = filename + ImStrlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {}
|
||||
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s", p);
|
||||
ImFormatString(font_cfg.Name, IM_COUNTOF(font_cfg.Name), "%s", p);
|
||||
}
|
||||
return AddFontFromMemoryTTF(data, (int)data_size, size_pixels, &font_cfg, glyph_ranges);
|
||||
}
|
||||
@@ -3211,6 +3260,9 @@ void ImFontAtlasBuildNotifySetFont(ImFontAtlas* atlas, ImFont* old_font, ImFont*
|
||||
shared_data->Font = new_font;
|
||||
if (ImGuiContext* ctx = shared_data->Context)
|
||||
{
|
||||
if (ctx->FrameCount == 0 && old_font == NULL) // While this should work either way, we save ourselves the bother / debugging confusion of running ImGui code so early when it is not needed.
|
||||
continue;
|
||||
|
||||
if (ctx->IO.FontDefault == old_font)
|
||||
ctx->IO.FontDefault = new_font;
|
||||
if (ctx->Font == old_font)
|
||||
@@ -3233,7 +3285,6 @@ void ImFontAtlasBuildNotifySetFont(ImFontAtlas* atlas, ImFont* old_font, ImFont*
|
||||
void ImFontAtlas::RemoveFont(ImFont* font)
|
||||
{
|
||||
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
|
||||
font->ClearOutputData();
|
||||
|
||||
ImFontAtlasFontDestroyOutput(this, font);
|
||||
for (ImFontConfig* src : font->Sources)
|
||||
@@ -3396,6 +3447,7 @@ void ImFontAtlasBuildMain(ImFontAtlas* atlas)
|
||||
|
||||
void ImFontAtlasBuildGetOversampleFactors(ImFontConfig* src, ImFontBaked* baked, int* out_oversample_h, int* out_oversample_v)
|
||||
{
|
||||
// (Only used by stb_truetype builder)
|
||||
// Automatically disable horizontal oversampling over size 36
|
||||
const float raster_size = baked->Size * baked->RasterizerDensity * src->RasterizerDensity;
|
||||
*out_oversample_h = (src->OversampleH != 0) ? src->OversampleH : (raster_size > 36.0f || src->PixelSnapH) ? 1 : 2;
|
||||
@@ -3610,6 +3662,12 @@ void ImFontAtlasFontDestroyOutput(ImFontAtlas* atlas, ImFont* font)
|
||||
}
|
||||
}
|
||||
|
||||
void ImFontAtlasFontRebuildOutput(ImFontAtlas* atlas, ImFont* font)
|
||||
{
|
||||
ImFontAtlasFontDestroyOutput(atlas, font);
|
||||
ImFontAtlasFontInitOutput(atlas, font);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool ImFontAtlasFontSourceInit(ImFontAtlas* atlas, ImFontConfig* src)
|
||||
@@ -3638,7 +3696,7 @@ void ImFontAtlasFontDestroySourceData(ImFontAtlas* atlas, ImFontConfig* src)
|
||||
IM_UNUSED(atlas);
|
||||
// IF YOU GET A CRASH IN THE IM_FREE() CALL HERE AND USED AddFontFromMemoryTTF():
|
||||
// - DUE TO LEGACY REASON AddFontFromMemoryTTF() TRANSFERS MEMORY OWNERSHIP BY DEFAULT.
|
||||
// - IT WILL THEREFORE CRASH WHEN PASSED DATA WHICH MAY NOT BE FREEED BY IMGUI.
|
||||
// - IT WILL THEREFORE CRASH WHEN PASSED DATA WHICH MAY NOT BE FREED BY IMGUI.
|
||||
// - USE `ImFontConfig font_cfg; font_cfg.FontDataOwnedByAtlas = false; io.Fonts->AddFontFromMemoryTTF(....., &cfg);` to disable passing ownership/
|
||||
// WE WILL ADDRESS THIS IN A FUTURE REWORK OF THE API.
|
||||
if (src->FontDataOwnedByAtlas)
|
||||
@@ -4009,7 +4067,7 @@ static void ImFontAtlasDebugWriteTexToDisk(ImTextureData* tex, const char* descr
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
char buf[128];
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "[%05d] Texture #%03d - %s.png", g.FrameCount, tex->UniqueID, description);
|
||||
ImFormatString(buf, IM_COUNTOF(buf), "[%05d] Texture #%03d - %s.png", g.FrameCount, tex->UniqueID, description);
|
||||
stbi_write_png(buf, tex->Width, tex->Height, tex->BytesPerPixel, tex->Pixels, tex->GetPitch()); // tex->BytesPerPixel is technically not component, but ok for the formats we support.
|
||||
}
|
||||
#endif
|
||||
@@ -4238,6 +4296,10 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
|
||||
ImFontAtlasUpdateDrawListsSharedData(atlas);
|
||||
|
||||
//atlas->TexIsBuilt = true;
|
||||
|
||||
// Lazily initialize char/text classifier
|
||||
// FIXME: This could be practically anywhere, and should eventually be parameters to CalcTextSize/word-wrapping code, but there's no obvious spot now.
|
||||
ImTextInitClassifiers();
|
||||
}
|
||||
|
||||
// Destroy builder and all cached glyphs. Do not destroy actual fonts.
|
||||
@@ -4544,16 +4606,16 @@ void ImFontAtlasDebugLogTextureRequests(ImFontAtlas* atlas)
|
||||
if (tex->Status == ImTextureStatus_WantCreate)
|
||||
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: create %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||
else if (tex->Status == ImTextureStatus_WantDestroy)
|
||||
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: destroy %dx%d, texid=0x%" IM_PRIX64 ", backend_data=%p\n", tex->UniqueID, tex->Width, tex->Height, IM_TEXTUREID_TO_U64(tex->TexID), tex->BackendUserData);
|
||||
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: destroy %dx%d, texid=0x%" IM_PRIX64 ", backend_data=%p\n", tex->UniqueID, tex->Width, tex->Height, ImGui::DebugTextureIDToU64(tex->TexID), tex->BackendUserData);
|
||||
else if (tex->Status == ImTextureStatus_WantUpdates)
|
||||
{
|
||||
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update %d regions, texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, tex->Updates.Size, IM_TEXTUREID_TO_U64(tex->TexID), (ImU64)(intptr_t)tex->BackendUserData);
|
||||
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update %d regions, texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, tex->Updates.Size, ImGui::DebugTextureIDToU64(tex->TexID), (ImU64)(intptr_t)tex->BackendUserData);
|
||||
for (const ImTextureRect& r : tex->Updates)
|
||||
{
|
||||
IM_UNUSED(r);
|
||||
IM_ASSERT(r.x >= 0 && r.y >= 0);
|
||||
IM_ASSERT(r.x + r.w <= tex->Width && r.y + r.h <= tex->Height); // In theory should subtract PackPadding but it's currently part of atlas and mid-frame change would wreck assert.
|
||||
//IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update (% 4d..%-4d)->(% 4d..%-4d), texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, r.x, r.y, r.x + r.w, r.y + r.h, IM_TEXTUREID_TO_U64(tex->TexID), (ImU64)(intptr_t)tex->BackendUserData);
|
||||
//IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update (% 4d..%-4d)->(% 4d..%-4d), texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, r.x, r.y, r.x + r.w, r.y + r.h, ImGui::DebugTextureIDToU64(tex->TexID), (ImU64)(intptr_t)tex->BackendUserData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4583,14 +4645,14 @@ static bool ImGui_ImplStbTrueType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig*
|
||||
IM_ASSERT(src->FontLoaderData == NULL);
|
||||
|
||||
// Initialize helper structure for font loading and verify that the TTF/OTF data is correct
|
||||
const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)src->FontData, src->FontNo);
|
||||
const int font_offset = stbtt_GetFontOffsetForIndex((const unsigned char*)src->FontData, src->FontNo);
|
||||
if (font_offset < 0)
|
||||
{
|
||||
IM_DELETE(bd_font_data);
|
||||
IM_ASSERT_USER_ERROR(0, "stbtt_GetFontOffsetForIndex(): FontData is incorrect, or FontNo cannot be found.");
|
||||
return false;
|
||||
}
|
||||
if (!stbtt_InitFont(&bd_font_data->FontInfo, (unsigned char*)src->FontData, font_offset))
|
||||
if (!stbtt_InitFont(&bd_font_data->FontInfo, (const unsigned char*)src->FontData, font_offset))
|
||||
{
|
||||
IM_DELETE(bd_font_data);
|
||||
IM_ASSERT_USER_ERROR(0, "stbtt_InitFont(): failed to parse FontData. It is correct and complete? Check FontDataSize.");
|
||||
@@ -4602,12 +4664,10 @@ static bool ImGui_ImplStbTrueType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig*
|
||||
if (src->MergeMode && src->SizePixels == 0.0f)
|
||||
src->SizePixels = ref_size;
|
||||
|
||||
if (src->SizePixels >= 0.0f)
|
||||
bd_font_data->ScaleFactor = stbtt_ScaleForPixelHeight(&bd_font_data->FontInfo, 1.0f);
|
||||
else
|
||||
bd_font_data->ScaleFactor = stbtt_ScaleForMappingEmToPixels(&bd_font_data->FontInfo, 1.0f);
|
||||
bd_font_data->ScaleFactor = stbtt_ScaleForPixelHeight(&bd_font_data->FontInfo, 1.0f);
|
||||
if (src->MergeMode && src->SizePixels != 0.0f && ref_size != 0.0f)
|
||||
bd_font_data->ScaleFactor *= src->SizePixels / ref_size; // FIXME-NEWATLAS: Should tidy up that a bit
|
||||
bd_font_data->ScaleFactor *= src->ExtraSizeScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -4640,7 +4700,7 @@ static bool ImGui_ImplStbTrueType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig
|
||||
{
|
||||
// FIXME-NEWFONTS: reevaluate how to use sizing metrics
|
||||
// FIXME-NEWFONTS: make use of line gap value
|
||||
float scale_for_layout = bd_font_data->ScaleFactor * baked->Size;
|
||||
const float scale_for_layout = bd_font_data->ScaleFactor * baked->Size / src->ExtraSizeScale;
|
||||
int unscaled_ascent, unscaled_descent, unscaled_line_gap;
|
||||
stbtt_GetFontVMetrics(&bd_font_data->FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap);
|
||||
baked->Ascent = ImCeil(unscaled_ascent * scale_for_layout);
|
||||
@@ -4715,12 +4775,8 @@ static bool ImGui_ImplStbTrueType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontC
|
||||
|
||||
const float ref_size = baked->OwnerFont->Sources[0]->SizePixels;
|
||||
const float offsets_scale = (ref_size != 0.0f) ? (baked->Size / ref_size) : 1.0f;
|
||||
float font_off_x = (src->GlyphOffset.x * offsets_scale);
|
||||
float font_off_y = (src->GlyphOffset.y * offsets_scale);
|
||||
if (src->PixelSnapH) // Snap scaled offset. This is to mitigate backward compatibility issues for GlyphOffset, but a better design would be welcome.
|
||||
font_off_x = IM_ROUND(font_off_x);
|
||||
if (src->PixelSnapV)
|
||||
font_off_y = IM_ROUND(font_off_y);
|
||||
float font_off_x = ImFloor(src->GlyphOffset.x * offsets_scale + 0.5f); // Snap scaled offset.
|
||||
float font_off_y = ImFloor(src->GlyphOffset.y * offsets_scale + 0.5f);
|
||||
font_off_x += sub_x;
|
||||
font_off_y += sub_y + IM_ROUND(baked->Ascent);
|
||||
float recip_h = 1.0f / (oversample_h * rasterizer_density);
|
||||
@@ -4892,11 +4948,11 @@ const ImWchar* ImFontAtlas::GetGlyphRangesChineseSimplifiedCommon()
|
||||
0xFF00, 0xFFEF, // Half-width characters
|
||||
0xFFFD, 0xFFFD // Invalid
|
||||
};
|
||||
static ImWchar full_ranges[IM_ARRAYSIZE(base_ranges) + IM_ARRAYSIZE(accumulative_offsets_from_0x4E00) * 2 + 1] = { 0 };
|
||||
static ImWchar full_ranges[IM_COUNTOF(base_ranges) + IM_COUNTOF(accumulative_offsets_from_0x4E00) * 2 + 1] = { 0 };
|
||||
if (!full_ranges[0])
|
||||
{
|
||||
memcpy(full_ranges, base_ranges, sizeof(base_ranges));
|
||||
UnpackAccumulativeOffsetsIntoRanges(0x4E00, accumulative_offsets_from_0x4E00, IM_ARRAYSIZE(accumulative_offsets_from_0x4E00), full_ranges + IM_ARRAYSIZE(base_ranges));
|
||||
UnpackAccumulativeOffsetsIntoRanges(0x4E00, accumulative_offsets_from_0x4E00, IM_COUNTOF(accumulative_offsets_from_0x4E00), full_ranges + IM_COUNTOF(base_ranges));
|
||||
}
|
||||
return &full_ranges[0];
|
||||
}
|
||||
@@ -4982,11 +5038,11 @@ const ImWchar* ImFontAtlas::GetGlyphRangesJapanese()
|
||||
0xFF00, 0xFFEF, // Half-width characters
|
||||
0xFFFD, 0xFFFD // Invalid
|
||||
};
|
||||
static ImWchar full_ranges[IM_ARRAYSIZE(base_ranges) + IM_ARRAYSIZE(accumulative_offsets_from_0x4E00)*2 + 1] = { 0 };
|
||||
static ImWchar full_ranges[IM_COUNTOF(base_ranges) + IM_COUNTOF(accumulative_offsets_from_0x4E00)*2 + 1] = { 0 };
|
||||
if (!full_ranges[0])
|
||||
{
|
||||
memcpy(full_ranges, base_ranges, sizeof(base_ranges));
|
||||
UnpackAccumulativeOffsetsIntoRanges(0x4E00, accumulative_offsets_from_0x4E00, IM_ARRAYSIZE(accumulative_offsets_from_0x4E00), full_ranges + IM_ARRAYSIZE(base_ranges));
|
||||
UnpackAccumulativeOffsetsIntoRanges(0x4E00, accumulative_offsets_from_0x4E00, IM_COUNTOF(accumulative_offsets_from_0x4E00), full_ranges + IM_COUNTOF(base_ranges));
|
||||
}
|
||||
return &full_ranges[0];
|
||||
}
|
||||
@@ -5075,12 +5131,12 @@ void ImFontGlyphRangesBuilder::BuildRanges(ImVector<ImWchar>* out_ranges)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] ImFont
|
||||
// [SECTION] ImFontBaked, ImFont
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ImFontBaked::ImFontBaked()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
FallbackGlyphIndex = -1;
|
||||
}
|
||||
|
||||
@@ -5097,7 +5153,7 @@ void ImFontBaked::ClearOutputData()
|
||||
|
||||
ImFont::ImFont()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
Scale = 1.0f;
|
||||
#endif
|
||||
@@ -5112,7 +5168,7 @@ void ImFont::ClearOutputData()
|
||||
{
|
||||
if (ImFontAtlas* atlas = OwnerAtlas)
|
||||
ImFontAtlasFontDiscardBakes(atlas, this, 0);
|
||||
FallbackChar = EllipsisChar = 0;
|
||||
//FallbackChar = EllipsisChar = 0;
|
||||
memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap));
|
||||
LastBaked = NULL;
|
||||
}
|
||||
@@ -5373,22 +5429,69 @@ const char* ImTextCalcWordWrapNextLineStart(const char* text, const char* text_e
|
||||
if ((flags & ImDrawTextFlags_WrapKeepBlanks) == 0)
|
||||
while (text < text_end && ImCharIsBlankA(*text))
|
||||
text++;
|
||||
if (*text == '\n')
|
||||
if (text < text_end && *text == '\n')
|
||||
text++;
|
||||
return text;
|
||||
}
|
||||
|
||||
void ImTextClassifierClear(ImU32* bits, unsigned int codepoint_min, unsigned int codepoint_end, ImWcharClass char_class)
|
||||
{
|
||||
for (unsigned int c = codepoint_min; c < codepoint_end; c++)
|
||||
ImTextClassifierSetCharClass(bits, codepoint_min, codepoint_end, char_class, c);
|
||||
}
|
||||
|
||||
void ImTextClassifierSetCharClass(ImU32* bits, unsigned int codepoint_min, unsigned int codepoint_end, ImWcharClass char_class, unsigned int c)
|
||||
{
|
||||
IM_ASSERT(c >= codepoint_min && c < codepoint_end);
|
||||
IM_UNUSED(codepoint_end);
|
||||
c -= codepoint_min;
|
||||
const ImU32 shift = (c & 15) << 1;
|
||||
bits[c >> 4] = (bits[c >> 4] & ~(0x03 << shift)) | (char_class << shift);
|
||||
}
|
||||
|
||||
void ImTextClassifierSetCharClassFromStr(ImU32* bits, unsigned int codepoint_min, unsigned int codepoint_end, ImWcharClass char_class, const char* s)
|
||||
{
|
||||
const char* s_end = s + strlen(s);
|
||||
while (*s)
|
||||
{
|
||||
unsigned int c;
|
||||
s += ImTextCharFromUtf8(&c, s, s_end);
|
||||
ImTextClassifierSetCharClass(bits, codepoint_min, codepoint_end, char_class, c);
|
||||
}
|
||||
}
|
||||
|
||||
#define ImTextClassifierGet(_BITS, _CHAR_OFFSET) ((_BITS[(_CHAR_OFFSET) >> 4] >> (((_CHAR_OFFSET) & 15) << 1)) & 0x03)
|
||||
|
||||
// 2-bit per character
|
||||
static ImU32 g_CharClassifierIsSeparator_0000_007f[128 / 16] = {};
|
||||
static ImU32 g_CharClassifierIsSeparator_3000_300f[ 16 / 16] = {};
|
||||
|
||||
void ImTextInitClassifiers()
|
||||
{
|
||||
if (ImTextClassifierGet(g_CharClassifierIsSeparator_0000_007f, ',') != 0)
|
||||
return;
|
||||
|
||||
// List of hardcoded separators: .,;!?'"
|
||||
// Making this dynamic given known ranges is trivial BUT requires us to standardize where you pass them as parameters. (#3002, #8503)
|
||||
ImTextClassifierClear(g_CharClassifierIsSeparator_0000_007f, 0, 128, ImWcharClass_Other);
|
||||
ImTextClassifierSetCharClassFromStr(g_CharClassifierIsSeparator_0000_007f, 0, 128, ImWcharClass_Blank, " \t");
|
||||
ImTextClassifierSetCharClassFromStr(g_CharClassifierIsSeparator_0000_007f, 0, 128, ImWcharClass_Punct, ".,;!?\"");
|
||||
|
||||
ImTextClassifierClear(g_CharClassifierIsSeparator_3000_300f, 0x3000, 0x300F, ImWcharClass_Other);
|
||||
ImTextClassifierSetCharClass(g_CharClassifierIsSeparator_3000_300f, 0x3000, 0x300F, ImWcharClass_Blank, 0x3000);
|
||||
ImTextClassifierSetCharClass(g_CharClassifierIsSeparator_3000_300f, 0x3000, 0x300F, ImWcharClass_Punct, 0x3001);
|
||||
ImTextClassifierSetCharClass(g_CharClassifierIsSeparator_3000_300f, 0x3000, 0x300F, ImWcharClass_Punct, 0x3002);
|
||||
}
|
||||
|
||||
// Simple word-wrapping for English, not full-featured. Please submit failing cases!
|
||||
// This will return the next location to wrap from. If no wrapping if necessary, this will fast-forward to e.g. text_end.
|
||||
// FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.)
|
||||
// Refer to imgui_test_suite's "drawlist_text_wordwrap_1" for tests.
|
||||
const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* text, const char* text_end, float wrap_width, ImDrawTextFlags flags)
|
||||
{
|
||||
// For references, possible wrap point marked with ^
|
||||
// "aaa bbb, ccc,ddd. eee fff. ggg!"
|
||||
// ^ ^ ^ ^ ^__ ^ ^
|
||||
|
||||
// List of hardcoded separators: .,;!?'"
|
||||
|
||||
// Skip extra blanks after a line returns (that includes not counting them in width computation)
|
||||
// e.g. "Hello world" --> "Hello" "World"
|
||||
|
||||
@@ -5399,16 +5502,20 @@ const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* t
|
||||
const float scale = size / baked->Size;
|
||||
|
||||
float line_width = 0.0f;
|
||||
float word_width = 0.0f;
|
||||
float blank_width = 0.0f;
|
||||
wrap_width /= scale; // We work with unscaled widths to avoid scaling every characters
|
||||
|
||||
const char* word_end = text;
|
||||
const char* prev_word_end = NULL;
|
||||
bool inside_word = true;
|
||||
|
||||
const char* s = text;
|
||||
IM_ASSERT(text_end != NULL);
|
||||
|
||||
int prev_type = ImWcharClass_Other;
|
||||
const bool keep_blanks = (flags & ImDrawTextFlags_WrapKeepBlanks) != 0;
|
||||
|
||||
// Find next wrapping point
|
||||
//const char* span_begin = s;
|
||||
const char* span_end = s;
|
||||
float span_width = 0.0f;
|
||||
|
||||
while (s < text_end)
|
||||
{
|
||||
unsigned int c = (unsigned int)*s;
|
||||
@@ -5424,7 +5531,7 @@ const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* t
|
||||
return s; // Direct return, skip "Wrap_width is too small to fit anything" path.
|
||||
if (c == '\r')
|
||||
{
|
||||
s = next_s;
|
||||
s = next_s; // Fast-skip
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -5434,46 +5541,56 @@ const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* t
|
||||
if (char_width < 0.0f)
|
||||
char_width = BuildLoadGlyphGetAdvanceOrFallback(baked, c);
|
||||
|
||||
if (ImCharIsBlankW(c))
|
||||
// Classify current character
|
||||
int curr_type;
|
||||
if (c < 128)
|
||||
curr_type = ImTextClassifierGet(g_CharClassifierIsSeparator_0000_007f, c);
|
||||
else if (c >= 0x3000 && c < 0x3010)
|
||||
curr_type = ImTextClassifierGet(g_CharClassifierIsSeparator_3000_300f, c & 15); //-V578
|
||||
else
|
||||
curr_type = ImWcharClass_Other;
|
||||
|
||||
if (curr_type == ImWcharClass_Blank)
|
||||
{
|
||||
if (inside_word)
|
||||
// End span: 'A ' or '. '
|
||||
if (prev_type != ImWcharClass_Blank && !keep_blanks)
|
||||
{
|
||||
line_width += blank_width;
|
||||
blank_width = 0.0f;
|
||||
word_end = s;
|
||||
span_end = s;
|
||||
line_width += span_width;
|
||||
span_width = 0.0f;
|
||||
}
|
||||
blank_width += char_width;
|
||||
inside_word = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
word_width += char_width;
|
||||
if (inside_word)
|
||||
// End span: '.X' unless X is a digit
|
||||
if (prev_type == ImWcharClass_Punct && curr_type != ImWcharClass_Punct && !(c >= '0' && c <= '9')) // FIXME: Digit checks might be removed if allow custom separators (#8503)
|
||||
{
|
||||
word_end = next_s;
|
||||
span_end = s;
|
||||
line_width += span_width + blank_width;
|
||||
span_width = blank_width = 0.0f;
|
||||
}
|
||||
else
|
||||
// End span: 'A ' or '. '
|
||||
else if (prev_type == ImWcharClass_Blank && keep_blanks)
|
||||
{
|
||||
prev_word_end = word_end;
|
||||
line_width += word_width + blank_width;
|
||||
if ((flags & ImDrawTextFlags_WrapKeepBlanks) && line_width <= wrap_width)
|
||||
prev_word_end = s;
|
||||
word_width = blank_width = 0.0f;
|
||||
span_end = s;
|
||||
line_width += span_width + blank_width;
|
||||
span_width = blank_width = 0.0f;
|
||||
}
|
||||
|
||||
// Allow wrapping after punctuation.
|
||||
inside_word = (c != '.' && c != ',' && c != ';' && c != '!' && c != '?' && c != '\"' && c != 0x3001 && c != 0x3002);
|
||||
span_width += char_width;
|
||||
}
|
||||
|
||||
// We ignore blank width at the end of the line (they can be skipped)
|
||||
if (line_width + word_width > wrap_width)
|
||||
if (span_width + blank_width + line_width > wrap_width)
|
||||
{
|
||||
// Words that cannot possibly fit within an entire line will be cut anywhere.
|
||||
if (word_width < wrap_width)
|
||||
s = prev_word_end ? prev_word_end : word_end;
|
||||
break;
|
||||
if (span_width + blank_width > wrap_width)
|
||||
break;
|
||||
// FIXME: Narrow wrapping e.g. "A quick brown" -> "Quic|k br|own", would require knowing if span is going to be longer than wrap_width.
|
||||
//if (span_width > wrap_width && !is_blank && !was_blank)
|
||||
// return s;
|
||||
return span_end;
|
||||
}
|
||||
|
||||
prev_type = curr_type;
|
||||
s = next_s;
|
||||
}
|
||||
|
||||
@@ -5497,8 +5614,8 @@ ImVec2 ImFontCalcTextSizeEx(ImFont* font, float size, float max_width, float wra
|
||||
text_end_display = text_end;
|
||||
|
||||
ImFontBaked* baked = font->GetFontBaked(size);
|
||||
const float line_height = size;
|
||||
const float scale = line_height / baked->Size;
|
||||
const float line_height = ImCeil(size * font->LineHeight);
|
||||
const float scale = size / baked->Size;
|
||||
|
||||
ImVec2 text_size = ImVec2(0, 0);
|
||||
float line_width = 0.0f;
|
||||
@@ -5625,7 +5742,7 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||
}
|
||||
|
||||
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
|
||||
// DO NOT CALL DIRECTLY THIS WILL CHANGE WILDLY IN 2025-2025. Use ImDrawList::AddText().
|
||||
// DO NOT CALL DIRECTLY THIS WILL CHANGE WILDLY IN 2026. Use ImDrawList::AddText().
|
||||
void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, ImDrawTextFlags flags)
|
||||
{
|
||||
// Align to be pixel perfect
|
||||
@@ -5638,7 +5755,7 @@ begin:
|
||||
if (!text_end)
|
||||
text_end = text_begin + ImStrlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
|
||||
|
||||
const float line_height = size;
|
||||
const float line_height = ImCeil(size * LineHeight);
|
||||
ImFontBaked* baked = GetFontBaked(size);
|
||||
|
||||
const float scale = size / baked->Size;
|
||||
@@ -5839,7 +5956,7 @@ begin:
|
||||
// - RenderBullet()
|
||||
// - RenderCheckMark()
|
||||
// - RenderArrowPointingAt()
|
||||
// - RenderRectFilledRangeH()
|
||||
// - RenderRectFilledInRangeH()
|
||||
// - RenderRectFilledWithHole()
|
||||
//-----------------------------------------------------------------------------
|
||||
// Function in need of a redesign (legacy mess)
|
||||
@@ -5922,15 +6039,15 @@ static inline float ImAcos01(float x)
|
||||
}
|
||||
|
||||
// FIXME: Cleanup and move code to ImDrawList.
|
||||
void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding)
|
||||
// - Before 2025-12-04: RenderRectFilledRangeH() with 'float x_start_norm, float x_end_norm` <- normalized
|
||||
// - After 2025-12-04: RenderRectFilledInRangeH() with 'float x1, float x2' <- absolute coords!!
|
||||
void ImGui::RenderRectFilledInRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float fill_x0, float fill_x1, float rounding)
|
||||
{
|
||||
if (x_end_norm == x_start_norm)
|
||||
if (fill_x0 > fill_x1)
|
||||
return;
|
||||
if (x_start_norm > x_end_norm)
|
||||
ImSwap(x_start_norm, x_end_norm);
|
||||
|
||||
ImVec2 p0 = ImVec2(ImLerp(rect.Min.x, rect.Max.x, x_start_norm), rect.Min.y);
|
||||
ImVec2 p1 = ImVec2(ImLerp(rect.Min.x, rect.Max.x, x_end_norm), rect.Max.y);
|
||||
ImVec2 p0 = ImVec2(fill_x0, rect.Min.y);
|
||||
ImVec2 p1 = ImVec2(fill_x1, rect.Max.y);
|
||||
if (rounding == 0.0f)
|
||||
{
|
||||
draw_list->AddRectFilled(p0, p1, col, 0.0f);
|
||||
@@ -5998,6 +6115,17 @@ void ImGui::RenderRectFilledWithHole(ImDrawList* draw_list, const ImRect& outer,
|
||||
if (fill_R && fill_D) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Max.y), ImVec2(outer.Max.x, outer.Max.y), col, rounding, ImDrawFlags_RoundCornersBottomRight);
|
||||
}
|
||||
|
||||
ImDrawFlags ImGui::CalcRoundingFlagsForRectInRect(const ImRect& r_in, const ImRect& r_outer, float threshold)
|
||||
{
|
||||
bool round_l = r_in.Min.x <= r_outer.Min.x + threshold;
|
||||
bool round_r = r_in.Max.x >= r_outer.Max.x - threshold;
|
||||
bool round_t = r_in.Min.y <= r_outer.Min.y + threshold;
|
||||
bool round_b = r_in.Max.y >= r_outer.Max.y - threshold;
|
||||
return ImDrawFlags_RoundCornersNone
|
||||
| ((round_t && round_l) ? ImDrawFlags_RoundCornersTopLeft : 0) | ((round_t && round_r) ? ImDrawFlags_RoundCornersTopRight : 0)
|
||||
| ((round_b && round_l) ? ImDrawFlags_RoundCornersBottomLeft : 0) | ((round_b && round_r) ? ImDrawFlags_RoundCornersBottomRight : 0);
|
||||
}
|
||||
|
||||
// Helper for ColorPicker4()
|
||||
// NB: This is rather brittle and will show artifact when rounding this enabled if rounded corners overlap multiple cells. Caller currently responsible for avoiding that.
|
||||
// Spent a non reasonable amount of time trying to getting this right for ColorButton with rounding+anti-aliasing+ImGuiColorEditFlags_HalfAlphaPreview flag + various grid sizes and offsets, and eventually gave up... probably more reasonable to disable rounding altogether.
|
||||
@@ -6161,11 +6289,8 @@ static unsigned int stb_decompress(unsigned char *output, const unsigned char *i
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Default font data (ProggyClean.ttf)
|
||||
//-----------------------------------------------------------------------------
|
||||
// ProggyClean.ttf
|
||||
// Copyright (c) 2004, 2005 Tristan Grimmer
|
||||
// MIT license (see License.txt in http://www.proggyfonts.net/index.php?menu=download)
|
||||
// Download and more information at http://www.proggyfonts.net or http://upperboundsinteractive.com/fonts.php
|
||||
// If you want a similar font which may be better scaled, consider using ProggyVector from the same author!
|
||||
// MIT License / Copyright (c) 2004, 2005 Tristan Grimmer
|
||||
// Download and more information at https://github.com/bluescan/proggyfonts
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
@@ -6343,11 +6468,274 @@ static const unsigned char proggy_clean_ttf_compressed_data[9583] =
|
||||
239,32,57,141,239,32,57,141,239,32,57,141,239,32,57,141,239,32,57,141,239,35,57,102,0,0,5,250,72,249,98,247,
|
||||
};
|
||||
|
||||
static const char* GetDefaultCompressedFontDataTTF(int* out_size)
|
||||
static const char* GetDefaultCompressedFontDataProggyClean(int* out_size)
|
||||
{
|
||||
*out_size = proggy_clean_ttf_compressed_size;
|
||||
return (const char*)proggy_clean_ttf_compressed_data;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Default font data (ProggyForever-Regular-minimal.ttf)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Based on ProggyForever: https://github.com/ocornut/proggyforever
|
||||
// MIT license / Copyright (c) 2026 Disco Hello, Copyright (c) 2019,2023 Tristan Grimmer
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// File: 'output/ProggyForever-Regular-minimal.ttf' (18556 bytes)
|
||||
// Exported using binary_to_compressed_c.exe -u8 "output/ProggyForever-Regular-minimal.ttf" proggy_forever_minimal_ttf
|
||||
static const unsigned int proggy_forever_minimal_ttf_compressed_size = 14562;
|
||||
static const unsigned char proggy_forever_minimal_ttf_compressed_data[14562] =
|
||||
{
|
||||
87,188,0,0,0,0,0,0,0,0,72,124,0,4,0,0,55,0,1,0,0,0,14,0,128,0,3,0,96,70,70,84,77,176,111,174,190,0,0,72,96,130,21,40,28,71,68,69,70,0,136,0,105,130,15,32,64,130,15,44,30,79,83,47,50,
|
||||
104,97,19,194,0,0,1,104,130,15,44,96,99,109,97,112,177,173,221,139,0,0,3,80,130,19,44,114,99,118,116,32,0,33,2,121,0,0,4,196,130,31,38,4,103,97,115,112,255,255,130,89,34,0,72,56,130,
|
||||
15,56,8,103,108,121,102,239,245,108,207,0,0,6,76,0,0,62,224,104,101,97,100,44,57,58,3,130,27,32,236,130,3,33,54,104,130,16,35,4,62,0,230,130,75,32,36,130,15,39,36,104,109,116,120,24,
|
||||
22,19,130,95,33,1,200,130,19,40,136,108,111,99,97,80,9,64,114,130,95,131,15,39,130,109,97,120,112,1,7,0,131,31,32,72,130,47,44,32,110,97,109,101,10,160,159,151,0,0,69,44,130,47,44,
|
||||
68,112,111,115,116,70,77,175,253,0,0,70,112,130,15,32,197,132,235,32,1,130,9,42,224,136,151,95,15,60,245,0,11,3,232,130,55,36,0,229,175,187,66,132,7,42,178,59,232,255,225,255,68,1,
|
||||
215,2,176,130,15,34,8,0,2,130,5,131,2,130,51,39,2,131,255,71,0,0,1,184,130,31,34,226,1,215,132,73,131,25,135,3,32,4,132,17,37,192,0,90,0,5,0,131,0,33,2,0,130,44,132,19,34,64,0,46,130,
|
||||
11,38,0,0,4,1,184,1,144,131,29,35,2,138,2,187,130,17,32,140,133,7,38,1,223,0,49,1,2,0,138,0,37,128,0,0,7,16,0,136,123,33,0,88,130,0,37,0,64,0,32,32,172,133,131,34,2,175,0,131,63,33,
|
||||
3,0,130,0,35,1,133,2,6,130,6,38,32,0,1,1,184,0,33,130,9,130,161,32,0,132,3,39,0,166,0,116,255,249,0,49,130,113,36,4,0,185,0,135,130,1,38,27,0,22,0,154,0,53,130,25,40,39,0,41,0,79,0,
|
||||
50,0,45,130,17,32,49,130,11,33,46,0,131,17,36,166,0,143,0,24,132,1,34,48,255,225,130,55,34,38,0,47,130,23,44,52,0,58,0,35,0,42,0,66,0,65,0,19,130,79,32,19,130,47,38,35,0,44,0,13,0,
|
||||
38,130,21,38,9,0,37,0,13,255,250,130,121,36,5,0,33,0,104,130,47,40,104,0,37,255,242,0,124,0,48,130,95,32,59,130,3,34,37,0,40,130,5,36,62,0,139,0,100,130,57,36,133,0,20,0,62,130,55,
|
||||
32,50,130,19,40,69,0,69,0,87,0,54,0,29,130,167,32,20,130,107,36,64,0,63,0,188,130,3,36,22,0,21,0,159,130,7,36,40,0,55,0,5,130,17,34,64,0,109,130,33,34,92,0,50,130,5,42,109,0,101,0,
|
||||
24,0,115,0,109,0,131,130,121,32,48,130,39,36,143,0,114,0,83,130,77,32,19,130,157,34,18,0,73,130,49,32,5,136,3,32,2,130,85,33,52,0,133,1,33,66,0,133,1,32,17,130,125,32,35,130,209,131,
|
||||
3,36,46,0,1,0,46,132,1,32,47,130,51,32,42,130,25,32,38,130,213,135,3,34,5,0,59,130,99,32,37,132,3,34,51,0,68,132,1,32,42,130,189,33,43,0,135,1,36,24,0,12,0,61,134,1,32,26,130,131,38,
|
||||
26,0,30,0,0,0,3,134,3,32,28,130,93,130,10,35,0,108,0,3,132,9,36,28,0,4,0,80,130,16,34,16,0,16,132,35,46,126,0,133,0,171,0,210,0,211,0,255,32,172,255,255,130,25,32,32,130,17,34,161,
|
||||
0,174,130,17,32,212,131,17,45,255,227,255,221,255,194,255,192,255,95,255,191,224,19,132,67,130,36,139,2,34,1,6,0,136,22,35,1,2,0,0,66,53,9,32,0,133,0,32,1,130,142,8,148,4,5,6,7,8,9,
|
||||
10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,
|
||||
70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,0,132,133,135,137,145,149,155,160,159,161,163,162,164,166,168,167,169,170,172,171,173,174,176,178,
|
||||
177,179,181,180,185,184,186,187,0,112,100,101,105,0,118,158,110,107,0,116,106,0,134,151,0,113,0,0,103,117,132,158,38,108,122,0,165,183,127,99,132,11,38,109,123,0,0,128,131,148,132,
|
||||
11,130,4,37,182,0,190,60,0,191,130,8,34,0,0,119,130,5,47,130,138,129,139,136,141,142,143,140,50,147,0,146,153,154,152,130,18,32,111,130,3,32,120,130,3,130,2,34,33,2,121,130,5,33,42,
|
||||
0,133,1,9,155,68,0,86,0,134,0,210,1,14,1,104,1,116,1,148,1,180,1,212,1,232,2,6,2,20,2,38,2,54,2,100,2,122,2,172,2,232,3,2,3,60,3,116,3,134,3,210,4,10,4,40,4,82,4,102,4,122,4,142,4,
|
||||
204,5,36,5,60,5,118,5,158,5,184,5,208,5,228,6,24,6,44,6,68,6,94,6,118,6,134,6,160,6,182,6,224,7,14,7,64,7,106,7,182,7,200,7,238,8,0,8,28,8,52,8,72,8,96,8,114,8,130,8,148,8,166,8,180,
|
||||
8,194,9,12,9,58,9,92,9,140,9,182,9,214,10,14,10,44,10,74,10,110,10,134,10,150,10,198,10,230,11,4,11,50,11,96,11,130,11,188,11,216,11,250,12,14,12,42,12,66,12,114,12,142,12,198,12,210,
|
||||
13,10,13,62,13,126,13,152,13,198,13,238,14,34,14,72,14,90,14,198,14,232,15,32,15,106,15,134,15,200,15,214,15,244,16,16,16,56,16,114,16,128,16,182,16,212,16,230,17,2,17,22,17,60,17,
|
||||
86,17,132,17,194,18,20,18,76,18,108,18,140,18,176,18,228,19,24,19,74,19,110,19,168,19,198,19,228,20,6,20,56,20,86,20,116,20,150,20,200,20,252,21,44,21,92,21,144,21,212,22,24,22,50,
|
||||
22,112,22,148,22,186,22,226,23,28,23,56,23,90,23,160,23,246,24,76,24,164,25,18,25,124,25,226,26,94,26,150,26,198,26,248,27,44,27,114,27,144,27,174,27,208,28,2,28,74,28,136,28,174,28,
|
||||
212,28,254,29,60,29,118,29,172,29,230,30,16,30,58,30,104,30,166,30,206,30,244,31,48,31,112,0,0,0,2,0,33,0,0,1,42,2,154,0,3,0,7,0,46,177,1,0,47,60,178,7,4,0,237,50,177,6,5,220,60,178,
|
||||
3,2,130,10,34,0,177,3,131,22,32,5,131,22,39,178,7,6,1,252,60,178,1,131,23,52,51,17,33,17,39,51,17,35,33,1,9,232,199,199,2,154,253,102,33,2,88,131,83,38,166,255,254,1,18,2,35,130,81,
|
||||
61,13,0,0,54,50,22,20,6,34,38,52,55,35,3,55,51,21,198,44,32,32,44,32,85,59,14,1,83,105,31,131,11,36,122,1,4,91,91,130,135,38,116,1,70,1,68,2,7,132,135,37,0,1,35,53,51,7,130,3,8,40,
|
||||
1,67,64,64,142,65,65,1,70,192,192,192,0,2,255,248,0,3,1,191,2,3,0,3,0,31,0,0,63,1,35,7,37,35,7,51,21,35,7,35,55,132,3,34,53,51,55,130,51,35,55,51,7,51,131,3,53,254,30,92,30,1,29,104,
|
||||
31,92,106,38,59,38,92,38,58,38,96,110,31,98,112,134,11,34,90,201,115,130,0,33,54,143,130,0,35,54,115,54,144,130,0,32,0,130,85,8,37,49,255,241,1,135,2,22,0,6,0,11,0,52,0,0,55,62,1,53,
|
||||
52,38,47,1,53,6,21,20,23,30,3,21,20,7,21,35,53,46,1,130,16,8,109,30,2,23,53,46,3,53,52,54,55,53,51,21,30,1,31,1,21,38,39,21,50,249,32,41,36,37,60,72,137,22,40,46,28,141,60,36,67,15,
|
||||
15,6,21,69,37,31,44,43,22,75,65,60,25,55,15,15,43,67,3,81,7,37,31,30,32,10,73,135,12,61,44,30,4,15,28,50,33,114,15,44,43,1,14,6,6,63,4,11,22,3,162,6,15,26,42,29,53,67,9,45,42,2,11,
|
||||
5,5,62,29,4,150,0,5,130,1,36,11,1,178,1,250,130,161,52,11,0,19,0,27,0,35,0,0,1,51,1,35,36,50,54,52,38,34,6,20,65,97,7,34,2,20,22,132,17,65,111,5,53,54,50,1,74,71,254,222,71,1,16,41,
|
||||
30,30,41,29,7,84,60,60,84,59,174,130,9,34,29,41,122,130,9,51,59,84,1,249,254,21,47,27,39,27,27,39,115,56,79,56,56,79,1,26,131,11,33,27,7,131,11,8,59,56,0,0,0,3,0,4,255,246,1,179,2,
|
||||
21,0,9,0,28,0,62,0,0,55,50,55,46,1,39,6,21,20,22,3,28,2,30,5,23,62,1,53,52,38,35,34,6,1,23,35,38,39,6,35,34,38,53,52,54,55,46,2,130,5,8,101,51,50,22,21,20,14,2,7,22,23,54,53,55,20,
|
||||
206,52,37,25,110,24,65,80,41,1,2,3,6,8,12,7,37,37,31,23,24,35,1,2,67,72,13,21,60,89,72,104,52,44,22,19,15,63,60,61,51,15,32,25,24,89,58,36,61,44,36,28,131,28,54,59,48,62,1,125,1,7,
|
||||
3,7,5,10,9,13,16,9,25,40,24,21,25,32,254,143,79,15,24,49,96,66,50,74,33,25,130,17,56,41,69,55,49,20,36,34,20,17,107,69,65,72,1,108,0,1,0,185,1,70,0,255,2,8,130,189,42,0,19,35,53,51,
|
||||
254,68,68,1,71,193,130,23,8,59,135,255,193,1,49,2,62,0,17,0,0,1,14,1,20,22,23,35,46,4,52,62,2,63,1,1,49,43,55,55,43,60,4,15,38,29,24,23,32,33,11,11,2,61,60,177,161,177,60,6,21,68,70,
|
||||
103,97,102,75,61,16,16,130,50,32,0,138,63,34,19,30,4,130,220,40,15,1,35,62,1,52,38,39,195,137,57,32,60,131,73,44,2,61,6,22,68,71,103,97,101,75,60,16,16,132,73,32,0,131,63,38,27,0,69,
|
||||
1,157,1,199,132,127,8,41,7,23,7,39,21,35,53,7,39,55,39,55,23,53,51,21,55,1,157,131,131,33,128,64,129,32,131,131,32,129,64,128,1,77,71,71,50,70,142,142,70,50,134,7,49,0,1,0,22,0,74,
|
||||
1,162,1,185,0,11,0,0,19,51,21,35,130,62,130,221,37,53,51,251,166,166,62,130,2,38,1,31,59,154,154,59,154,130,39,39,154,255,129,1,30,0,107,0,130,180,32,54,65,133,5,8,37,15,1,39,54,55,
|
||||
46,1,53,52,209,45,31,21,31,30,11,11,26,55,10,17,25,107,32,22,32,61,40,32,7,7,37,48,41,1,31,21,22,131,163,54,53,0,227,1,131,1,32,0,3,0,0,37,33,53,33,1,131,254,178,1,78,228,60,132,191,
|
||||
40,166,255,255,1,18,0,105,0,7,67,209,9,67,203,5,37,105,31,44,31,31,44,132,35,38,39,255,222,1,144,2,39,131,63,49,9,1,35,1,1,144,254,221,69,1,34,2,39,253,184,2,72,0,130,21,8,73,41,255,
|
||||
247,1,143,2,14,0,10,0,21,0,27,0,0,55,50,62,3,53,52,39,7,22,19,34,14,3,21,20,23,55,38,39,50,16,35,34,16,220,17,28,30,21,14,4,190,27,57,17,28,31,20,14,4,189,26,57,178,178,178,51,7,26,
|
||||
44,78,53,40,34,230,52,1,161,8,131,10,39,39,33,229,52,58,253,234,2,130,186,41,0,1,0,79,0,0,1,104,2,7,130,91,40,0,19,39,55,51,17,51,21,33,130,5,50,81,1,106,68,105,254,233,1,105,1,103,
|
||||
81,78,254,55,61,61,1,122,130,43,32,50,130,43,37,134,2,17,0,31,0,130,43,49,62,2,51,50,30,2,21,20,6,15,1,33,21,33,53,52,55,54,67,247,5,8,58,35,34,6,7,55,1,8,29,81,37,48,72,36,17,44,59,
|
||||
147,1,1,254,173,13,1,165,37,40,58,45,26,75,24,1,159,65,5,16,27,30,48,46,21,40,78,58,146,61,46,14,12,1,165,38,80,33,33,47,27,13,0,130,94,41,0,45,255,246,1,139,2,16,0,41,130,12,32,22,
|
||||
130,93,38,35,34,38,47,1,53,30,130,108,40,54,53,52,38,43,1,53,51,50,131,8,130,101,37,15,1,53,54,51,50,131,35,8,62,1,26,112,107,85,34,78,22,23,7,25,80,41,57,65,65,49,64,64,46,56,55,45,
|
||||
33,72,20,20,74,68,78,98,51,1,22,30,109,65,84,13,7,6,69,4,12,19,51,49,46,52,58,45,38,37,43,14,7,7,64,23,74,59,50,55,130,119,34,2,0,22,130,111,45,162,2,7,0,2,0,13,0,0,37,17,3,59,1,66,
|
||||
44,6,54,19,51,1,16,179,237,88,88,67,241,208,100,181,1,18,254,238,58,123,123,73,1,66,130,46,33,0,49,130,171,32,135,130,51,37,40,0,0,19,17,33,130,47,130,143,37,30,3,21,20,14,2,137,181,
|
||||
36,62,2,53,52,46,130,15,8,68,6,7,72,1,33,221,24,41,25,48,51,38,24,35,61,67,38,43,70,14,14,7,24,76,38,21,39,39,23,23,40,44,25,28,56,14,1,2,1,4,59,127,11,10,25,38,63,40,49,72,38,18,11,
|
||||
6,5,71,4,11,19,11,25,48,33,33,48,25,12,13,7,130,157,55,41,255,248,1,143,2,8,0,9,0,37,0,0,55,50,53,52,35,34,6,21,20,22,19,65,139,5,130,119,42,53,52,62,2,51,50,22,31,1,21,38,131,26,8,
|
||||
58,54,224,101,101,41,59,59,51,31,56,49,29,91,82,87,98,36,63,79,48,24,46,11,10,31,59,69,89,36,48,119,121,57,64,63,56,1,39,20,40,68,43,90,89,114,136,73,110,63,31,8,4,3,66,25,95,98,72,
|
||||
0,130,0,38,1,0,46,0,0,1,138,130,227,32,6,130,227,8,42,53,33,21,3,35,19,46,1,91,197,78,190,1,203,59,29,254,23,1,202,0,0,3,0,39,255,246,1,145,2,17,0,15,0,31,0,52,0,0,54,50,62,2,130,243,
|
||||
38,34,14,2,20,30,1,18,132,6,32,2,132,18,35,1,23,30,1,65,210,5,35,53,52,55,38,68,239,7,8,50,199,42,32,32,18,18,33,32,40,32,33,18,18,32,72,37,29,29,16,17,29,28,36,28,30,16,16,29,33,48,
|
||||
52,104,76,77,104,99,84,95,71,70,96,45,7,20,42,63,42,19,7,7,19,130,6,43,20,1,166,6,17,37,53,37,16,6,6,16,130,6,59,17,191,16,72,52,69,78,77,70,107,33,30,91,62,69,70,61,90,0,2,0,41,0,
|
||||
0,1,143,2,16,65,43,5,43,19,34,21,20,51,50,54,53,52,38,3,34,69,108,11,65,170,5,32,22,131,26,8,44,6,215,100,100,42,59,60,51,30,57,48,29,91,82,86,99,36,64,79,47,24,46,11,11,32,59,68,89,
|
||||
35,1,216,120,120,56,64,64,56,254,217,20,39,68,44,89,90,65,44,6,35,3,4,65,24,65,44,5,55,2,0,166,0,81,1,18,1,171,0,7,0,15,0,0,18,34,38,52,54,50,22,20,6,71,199,6,38,242,44,32,32,44,32,
|
||||
76,132,5,39,1,65,31,44,31,31,44,165,132,5,32,0,130,0,36,2,0,143,255,209,134,59,32,24,140,59,35,21,20,14,2,68,137,8,37,243,45,31,31,45,31,130,67,41,22,30,31,11,10,27,55,10,17,25,135,
|
||||
74,37,32,22,33,60,41,31,68,150,10,8,37,0,1,0,24,0,84,1,160,1,176,0,6,0,0,19,37,21,13,1,21,37,24,1,135,254,200,1,56,254,121,1,30,145,62,111,112,62,145,132,123,38,24,0,152,1,159,1,114,
|
||||
72,67,5,34,37,33,53,132,1,33,1,159,130,37,32,135,131,3,35,153,59,99,59,130,39,141,79,37,5,21,5,53,45,1,131,79,32,121,130,79,36,200,1,176,145,57,131,81,132,79,42,48,0,0,1,135,2,31,0,
|
||||
34,0,42,130,121,33,50,22,130,195,44,3,29,1,35,53,52,62,4,53,52,38,35,34,132,209,34,62,4,16,65,25,6,58,226,83,82,29,42,42,29,70,21,33,38,33,22,52,43,25,45,29,22,4,5,52,2,10,34,38,61,
|
||||
132,239,8,33,2,31,68,52,28,47,33,30,33,17,41,41,22,39,28,29,23,31,16,30,33,16,23,23,8,8,34,4,14,35,26,22,254,75,65,71,9,47,255,225,255,233,1,215,2,32,0,7,0,64,0,0,54,50,71,233,5,39,
|
||||
5,23,14,4,35,34,46,3,71,98,10,46,21,35,53,6,35,34,38,52,54,51,50,22,31,1,50,132,151,8,122,6,21,20,30,2,51,50,62,3,214,60,43,43,60,43,1,5,38,2,11,38,43,71,37,63,103,67,46,20,141,105,
|
||||
105,128,15,24,21,10,55,36,43,55,79,80,55,28,49,10,11,45,84,70,81,118,39,61,75,39,35,64,40,30,14,168,56,79,57,57,79,120,46,4,11,27,21,17,33,55,74,79,42,120,163,78,67,24,35,17,7,1,198,
|
||||
19,31,93,131,94,26,13,13,28,34,57,124,104,53,87,55,30,13,20,20,13,0,0,0,2,0,5,0,0,1,178,2,7,130,9,8,38,10,0,0,55,51,3,55,19,35,39,35,7,35,19,141,158,79,45,169,77,41,193,40,77,169,192,
|
||||
1,9,61,253,250,136,136,2,6,0,3,0,38,130,47,32,146,130,47,36,8,0,17,0,39,130,49,32,50,69,22,5,36,21,17,21,22,55,131,10,42,35,23,30,4,21,20,14,2,43,1,17,69,159,6,8,61,220,65,52,62,45,
|
||||
121,71,39,84,49,42,77,12,23,34,25,18,30,50,57,31,194,177,43,62,32,15,49,58,47,52,47,43,189,1,147,156,1,2,4,76,42,33,183,3,7,20,27,48,31,38,57,32,14,2,5,25,43,46,24,42,55,130,110,47,
|
||||
0,47,255,248,1,137,2,18,0,26,0,0,37,21,6,35,67,62,7,58,23,21,38,35,34,14,2,21,20,30,1,51,50,1,136,49,79,56,86,50,24,112,104,77,51,51,77,130,65,55,15,26,66,50,77,93,73,28,42,74,95,58,
|
||||
117,151,32,71,45,33,59,74,46,62,91,59,130,233,130,183,33,1,144,130,195,34,6,0,13,131,193,33,53,52,130,172,58,19,50,17,16,35,7,17,199,125,125,84,84,201,200,160,58,202,201,254,109,1,
|
||||
204,254,253,254,254,1,130,247,34,1,0,52,130,136,32,131,130,51,8,34,11,0,0,19,33,21,33,23,51,21,35,21,33,21,33,53,1,77,254,253,1,227,228,1,4,254,178,2,6,59,153,59,188,59,0,130,0,38,
|
||||
1,0,58,0,0,1,126,130,47,32,9,132,47,34,35,31,1,130,47,40,35,58,1,67,249,1,181,182,74,130,41,35,158,1,59,241,130,34,33,0,35,130,219,32,148,130,219,32,36,130,219,38,39,35,53,51,21,14,
|
||||
4,149,224,47,62,1,1,78,1,99,170,2,7,27,32,54,30,56,85,51,130,233,33,78,50,132,233,47,14,25,66,50,27,42,11,67,141,58,223,2,7,18,13,11,143,241,37,11,7,0,1,0,42,130,108,32,141,133,191,
|
||||
57,51,17,51,21,51,53,51,17,35,53,35,21,43,75,204,75,75,204,2,6,212,212,253,250,247,246,130,39,32,66,130,39,32,117,133,39,36,19,53,33,21,35,130,43,55,5,53,55,17,67,1,50,116,116,254,
|
||||
206,115,1,203,59,59,254,112,58,1,57,1,1,145,132,231,36,65,255,249,1,118,130,47,32,13,130,231,8,33,51,17,20,6,35,7,53,51,50,54,53,17,35,158,216,66,78,164,147,48,37,140,2,6,254,158,80,
|
||||
90,1,57,48,58,1,47,130,50,39,0,1,0,19,0,0,1,165,137,139,59,55,51,7,19,35,3,7,21,19,75,233,85,212,221,90,180,57,2,6,230,230,212,254,206,1,4,57,202,130,48,34,1,0,49,130,47,32,135,130,
|
||||
47,50,5,0,0,55,17,51,17,33,21,49,75,1,10,1,2,5,254,53,58,132,31,131,79,32,164,130,31,56,12,0,0,51,17,51,23,55,51,17,7,17,3,35,3,17,20,100,99,101,100,65,107,57,106,130,130,42,254,253,
|
||||
251,1,1,197,254,239,1,19,254,130,52,34,1,0,41,130,83,32,142,65,159,5,35,51,3,51,19,130,86,130,48,38,45,3,98,186,72,95,186,130,46,55,90,1,166,253,250,1,166,254,90,0,0,2,0,35,255,250,
|
||||
1,149,2,18,0,5,0,25,130,229,63,50,16,35,34,16,18,50,62,3,52,46,3,34,14,3,20,30,2,220,184,184,184,167,34,27,30,20,13,13,20,30,27,131,8,33,14,14,130,22,50,17,253,234,2,22,254,37,8,26,
|
||||
43,78,106,78,44,26,8,8,26,44,130,8,33,43,26,130,179,38,2,0,44,255,255,1,139,132,179,32,30,131,83,71,166,5,45,43,1,21,55,50,22,21,20,6,43,1,28,1,30,130,3,8,47,49,35,17,50,206,32,46,
|
||||
22,10,10,21,42,30,93,99,85,91,85,84,108,1,1,75,174,1,10,19,31,31,17,17,31,31,18,195,252,80,70,71,89,5,21,55,48,50,29,2,6,130,90,45,0,2,0,13,255,184,1,171,2,15,0,12,0,32,131,91,39,17,
|
||||
20,7,23,21,35,39,6,143,182,39,198,184,40,84,48,82,40,58,147,187,40,14,254,245,123,67,97,44,91,27,149,193,38,2,0,38,0,0,1,145,130,191,34,9,0,24,130,99,34,35,21,22,73,125,5,35,15,1,35,
|
||||
17,73,20,5,8,45,7,23,35,39,38,213,99,68,39,34,51,53,139,3,72,179,79,83,57,44,122,79,111,97,1,205,184,1,2,2,46,45,43,47,242,218,2,5,89,69,45,69,16,229,217,1,130,184,42,1,0,42,255,246,
|
||||
1,141,2,17,0,54,130,91,44,21,46,2,35,34,6,21,20,30,7,23,30,3,73,135,16,32,39,69,75,6,8,95,30,2,23,1,109,6,21,67,35,62,61,6,14,11,25,12,31,9,33,1,23,42,48,29,101,89,43,78,18,18,7,27,
|
||||
86,45,45,66,61,69,34,48,47,24,103,87,18,40,32,27,8,1,245,71,4,13,21,41,48,11,18,15,11,10,5,7,3,5,1,4,17,33,58,39,78,74,16,9,8,73,5,16,27,46,45,46,37,14,6,17,31,50,34,72,82,5,8,9,84,
|
||||
93,5,32,9,130,143,32,175,130,235,32,7,130,233,56,53,33,21,35,17,7,17,10,1,164,172,75,1,203,59,59,254,54,1,1,203,0,1,0,37,130,187,32,147,130,35,32,24,66,163,5,32,20,74,49,5,8,50,17,
|
||||
51,17,20,14,3,34,46,3,37,76,6,19,43,32,67,48,75,6,22,38,68,95,70,38,22,7,166,1,96,254,153,26,35,34,18,54,67,1,95,254,173,33,48,53,33,22,21,32,50,44,130,75,32,13,130,111,32,171,130,
|
||||
75,8,32,6,0,0,51,3,51,27,1,51,3,174,161,73,134,134,72,161,2,6,254,58,1,198,253,250,0,1,255,249,0,0,1,190,130,35,32,12,135,35,131,38,47,35,11,1,75,81,63,58,63,83,64,57,64,81,73,72,73,
|
||||
130,47,44,99,1,157,254,98,1,158,253,250,1,184,254,72,130,55,32,255,130,55,32,185,67,123,5,8,33,19,39,51,23,55,51,7,19,35,39,7,35,184,160,80,121,123,81,165,177,80,141,141,80,1,19,243,
|
||||
195,195,243,254,237,218,218,130,139,32,5,130,47,32,178,130,47,36,8,0,0,55,3,131,47,50,3,21,35,182,176,79,135,134,80,177,75,234,1,28,228,228,254,227,233,130,34,33,0,33,130,4,32,151,
|
||||
130,39,32,9,65,35,5,60,1,33,21,5,53,1,41,1,102,254,224,1,40,254,138,1,24,1,203,59,53,254,106,58,1,56,1,147,0,130,42,41,0,104,255,189,1,80,2,73,0,7,130,12,55,39,17,51,21,35,17,51,1,
|
||||
79,162,162,231,231,2,18,1,253,226,56,2,140,0,1,0,76,151,10,41,19,1,35,1,109,1,35,70,254,222,76,150,7,130,31,138,67,52,19,51,17,35,53,51,17,7,104,231,231,163,163,2,73,253,116,56,2,30,
|
||||
1,130,90,37,0,37,1,63,1,147,65,75,5,33,19,23,131,233,45,55,252,150,82,100,101,82,150,2,6,198,141,141,198,131,139,55,255,241,255,190,1,199,255,247,0,3,0,0,5,33,53,33,1,198,254,44,1,
|
||||
212,66,56,131,27,39,0,124,1,160,1,60,2,57,131,27,131,63,39,207,108,82,109,2,57,153,153,130,27,8,175,2,0,48,255,246,1,136,1,143,0,17,0,54,0,0,55,50,62,3,53,34,35,38,14,4,21,20,22,39,
|
||||
52,62,3,23,48,60,1,46,6,35,7,53,50,54,51,21,50,30,2,21,7,35,54,39,6,35,34,38,204,32,48,23,13,2,10,21,24,45,39,32,22,13,51,118,28,50,69,81,45,2,3,7,9,15,18,26,16,122,18,58,34,38,58,
|
||||
52,29,1,61,2,2,38,99,64,79,44,26,33,49,27,17,1,2,3,10,18,28,20,37,35,72,36,51,28,16,1,1,14,7,17,10,16,10,12,7,5,2,54,2,1,12,33,65,47,241,25,27,61,63,0,0,2,0,50,255,247,1,134,2,49,0,
|
||||
9,0,30,0,0,54,50,54,53,52,38,34,6,21,20,39,62,4,67,150,5,130,127,8,57,47,1,7,35,17,51,172,112,50,51,110,52,3,1,5,18,23,42,25,71,87,88,59,32,62,16,15,7,61,68,45,82,68,67,83,83,67,68,
|
||||
212,3,8,20,16,12,102,101,98,106,29,15,15,49,2,47,0,1,0,59,130,91,32,125,130,239,35,20,0,0,1,131,84,36,22,51,50,55,21,72,197,7,8,34,23,21,38,1,13,65,72,72,65,62,49,47,78,85,110,110,
|
||||
85,78,47,49,1,89,74,76,76,74,43,65,32,106,196,106,32,65,43,139,159,32,7,133,159,133,158,38,19,51,17,35,39,14,4,130,155,8,35,53,52,54,51,50,30,2,31,1,122,200,48,104,48,200,68,62,6,3,
|
||||
8,26,27,41,20,59,88,87,70,25,42,24,17,3,4,45,150,131,158,51,1,109,253,209,49,3,7,21,15,13,106,98,101,102,12,17,17,6,7,0,130,0,34,2,0,37,130,163,32,147,130,163,37,5,0,26,0,0,19,130,
|
||||
165,35,51,52,7,20,130,168,32,54,133,169,132,95,8,42,22,29,1,32,227,47,69,224,227,62,67,42,62,46,70,82,89,109,105,79,91,90,254,218,1,89,68,48,116,165,56,79,18,21,64,29,109,95,93,110,
|
||||
97,73,48,130,83,42,1,0,40,0,3,1,144,2,36,0,19,132,247,37,29,1,51,21,35,17,130,1,33,53,51,130,77,61,59,1,21,1,40,35,31,125,125,68,122,122,65,64,108,1,237,25,37,75,57,254,217,1,39,57,
|
||||
52,78,62,55,133,147,36,50,255,70,1,134,130,147,32,9,73,49,5,77,51,8,44,51,17,20,6,43,1,53,51,50,62,2,61,1,137,254,8,60,22,23,222,99,99,53,51,51,159,61,90,81,130,136,28,42,23,10,1,5,
|
||||
18,24,42,25,71,91,91,60,48,52,28,53,142,150,82,68,65,77,1,80,254,110,86,86,58,22,36,37,18,59,2,6,16,12,10,101,100,98,101,20,29,130,162,41,0,62,0,1,1,122,2,49,0,18,74,253,5,8,45,17,
|
||||
35,53,52,38,35,34,6,29,1,35,17,51,21,54,253,53,72,68,40,37,47,56,68,68,37,1,146,78,67,255,0,250,45,48,61,59,223,2,47,218,60,0,2,0,139,130,59,38,45,2,30,0,11,0,17,130,74,8,40,35,34,
|
||||
61,1,52,59,1,50,29,1,20,7,53,51,17,35,17,1,35,56,10,10,56,9,161,161,68,1,202,10,64,9,9,64,10,127,59,254,123,1,74,130,232,34,2,0,100,130,231,32,84,130,59,34,12,0,24,130,121,130,47,32,
|
||||
20,132,221,35,54,53,17,55,138,72,39,165,174,127,112,105,29,37,59,132,72,43,1,76,58,254,98,161,59,52,50,1,100,126,133,79,39,0,1,0,41,0,2,1,142,132,131,38,0,55,23,35,39,7,21,130,183,
|
||||
53,17,55,51,210,188,81,154,51,70,70,181,80,245,243,201,45,156,2,27,254,201,161,130,118,130,47,32,133,130,179,36,51,2,8,0,5,130,117,131,164,41,35,133,173,69,104,2,7,253,250,1,72,63,
|
||||
5,46,20,255,254,1,164,1,143,0,30,0,0,1,50,22,21,130,198,36,52,35,34,6,7,138,7,48,51,21,54,51,50,23,62,1,1,68,43,52,61,52,26,26,3,132,4,52,62,62,31,42,52,26,13,48,1,143,69,53,254,234,
|
||||
1,5,84,34,37,254,238,130,6,42,33,36,254,236,1,133,18,29,49,22,27,130,128,32,1,65,111,5,33,1,147,65,111,20,32,23,65,111,9,33,64,4,65,112,12,35,1,133,48,60,66,31,5,42,42,255,247,1,141,
|
||||
1,144,0,9,0,17,67,179,11,32,18,130,171,8,40,20,32,53,52,174,92,58,59,90,59,21,166,94,254,158,44,72,80,80,70,70,80,80,1,28,102,102,205,205,102,0,2,0,50,255,78,1,134,1,136,0,67,79,6,
|
||||
38,54,53,52,34,21,20,19,131,57,8,62,6,35,34,46,2,47,1,21,35,17,51,23,62,4,176,103,48,199,107,66,89,87,71,25,41,24,18,3,3,68,61,7,1,6,20,25,41,38,82,67,148,148,67,1,16,105,99,101,103,
|
||||
12,18,17,6,6,221,2,48,49,2,8,20,16,13,152,91,35,51,17,35,53,67,171,13,38,160,104,48,200,216,62,68,66,165,5,41,70,87,89,66,23,41,26,19,4,4,134,91,44,6,253,208,221,2,8,21,15,13,103,101,
|
||||
99,105,132,99,36,0,0,1,0,69,130,4,36,115,1,142,0,19,130,7,35,50,22,31,1,71,239,5,33,29,1,130,173,8,36,7,62,1,1,12,29,52,11,11,4,16,56,31,56,71,68,68,2,17,69,1,142,15,7,8,65,5,12,20,
|
||||
60,35,245,1,133,53,27,35,130,54,46,0,69,255,254,1,115,1,151,0,38,0,0,55,30,1,130,250,34,39,46,1,80,126,9,39,46,2,35,34,21,20,22,23,79,243,7,8,78,47,1,69,53,109,71,91,83,57,14,32,65,
|
||||
44,33,62,14,15,6,19,63,33,90,36,57,70,69,88,73,31,70,20,20,88,27,14,32,35,49,15,15,53,44,22,38,36,20,11,6,6,62,4,11,17,57,25,29,8,11,46,55,57,66,12,6,6,0,0,0,1,0,87,0,6,1,97,2,4,0,
|
||||
17,130,115,41,51,21,35,34,46,3,53,17,51,21,130,9,57,21,20,216,136,125,25,33,41,24,16,68,162,162,65,58,3,15,26,50,34,1,124,118,58,204,70,132,55,40,54,255,246,1,130,1,133,0,21,130,55,
|
||||
33,53,51,80,10,5,34,55,51,19,65,74,6,8,32,54,68,86,44,62,3,68,1,64,1,3,17,23,45,27,79,73,145,244,241,102,53,39,251,254,124,42,2,7,19,13,12,74,132,67,32,29,130,128,32,155,130,67,53,
|
||||
6,0,0,1,51,3,35,3,51,19,1,84,70,148,86,147,71,120,1,133,254,123,130,3,32,186,130,38,39,0,1,255,248,255,255,1,192,130,39,33,12,0,132,39,33,39,7,131,42,48,55,51,23,1,124,67,97,63,68,
|
||||
65,65,97,68,68,53,76,60,130,47,34,123,215,215,130,5,34,208,192,192,132,55,33,0,20,130,55,32,163,130,55,35,11,0,0,37,71,43,5,57,39,51,23,55,51,1,1,162,78,122,120,78,162,149,76,110,109,
|
||||
76,203,203,155,155,204,185,141,141,77,151,5,38,68,1,137,1,134,0,31,130,12,32,18,77,244,5,44,53,51,50,62,4,53,52,53,35,34,38,53,19,130,230,59,22,51,23,3,1,134,3,12,24,47,32,195,176,
|
||||
16,23,13,8,3,1,133,71,72,1,68,29,41,137,1,130,122,56,135,48,17,47,52,36,59,12,24,22,34,17,14,4,2,78,49,1,6,229,49,50,1,1,73,132,239,32,64,130,143,32,119,130,95,8,41,14,0,0,55,51,23,
|
||||
33,53,62,3,39,35,53,33,21,2,137,237,1,254,202,15,50,105,69,1,229,1,45,238,52,52,59,17,58,122,82,1,50,60,254,235,130,54,8,32,0,1,0,63,255,178,1,120,2,84,0,41,0,0,1,21,20,7,22,29,1,20,
|
||||
22,59,1,21,34,35,34,46,3,61,1,83,197,7,130,9,33,62,3,130,22,8,61,35,34,6,1,11,72,72,38,42,29,31,13,38,54,27,14,3,38,43,51,51,43,38,3,14,27,54,38,44,29,42,38,1,215,100,95,17,17,96,99,
|
||||
34,29,62,20,26,44,30,23,86,43,32,66,32,42,87,23,30,44,26,19,62,29,130,98,53,0,188,255,200,0,252,2,63,0,3,0,0,23,35,17,51,252,64,64,55,2,117,141,135,32,19,84,60,5,36,50,51,50,30,3,134,
|
||||
142,130,119,130,9,33,14,3,69,35,5,130,141,55,55,38,172,37,42,29,30,14,37,54,27,15,2,38,44,51,51,44,38,2,15,27,54,37,130,132,41,37,72,72,1,115,100,33,29,62,19,131,129,33,87,42,130,129,
|
||||
45,43,86,24,29,44,26,20,62,29,33,100,96,17,16,130,248,42,1,0,22,0,177,1,161,1,93,0,33,130,148,34,23,14,4,131,238,39,7,14,1,15,1,39,62,4,131,119,54,55,62,1,55,1,103,58,5,5,17,21,40,
|
||||
25,25,43,30,28,31,16,20,25,3,3,143,16,62,1,66,13,21,21,45,24,20,26,35,36,21,2,3,45,21,21,13,21,22,44,24,21,26,36,35,22,3,3,45,20,130,229,32,21,130,95,45,163,0,106,0,15,0,31,0,47,0,
|
||||
0,55,50,22,130,200,36,6,43,1,34,38,130,197,34,54,59,1,157,15,43,51,104,5,7,7,5,71,4,8,8,4,222,131,9,32,70,131,4,32,221,136,9,35,105,7,5,81,131,12,150,4,42,0,0,2,0,159,255,235,1,25,
|
||||
2,9,90,167,5,33,18,34,82,231,5,59,7,51,23,7,35,53,245,50,35,35,50,35,84,46,29,1,101,1,145,35,49,35,35,49,105,196,155,155,130,51,42,63,255,147,1,121,1,242,0,5,0,28,130,177,48,17,14,
|
||||
1,21,20,19,17,54,55,21,6,7,21,35,53,46,1,90,19,6,8,62,22,23,21,38,243,50,58,146,57,39,45,51,38,78,102,100,80,38,61,35,40,49,1,38,6,73,67,134,1,25,254,215,2,25,59,21,3,100,101,6,107,
|
||||
92,95,104,4,97,98,5,20,60,25,0,1,0,40,255,255,1,144,2,16,0,27,130,89,38,51,21,33,53,51,53,35,130,3,81,218,6,32,21,71,122,5,8,39,51,21,35,202,197,254,153,87,73,73,82,79,33,52,9,10,48,
|
||||
42,50,50,136,136,59,59,59,161,50,82,88,88,10,5,5,64,30,53,63,88,50,0,131,223,38,55,0,63,1,128,1,125,130,223,35,31,0,0,54,82,67,6,8,41,54,20,7,23,7,39,6,34,39,7,39,55,38,52,55,39,55,
|
||||
23,54,50,23,55,23,7,187,65,46,46,65,46,204,22,60,34,62,31,73,31,62,34,60,22,137,10,49,148,44,61,43,43,61,67,73,30,57,35,60,19,19,60,35,57,30,137,10,75,219,10,36,24,0,0,1,7,130,160,
|
||||
33,7,21,88,161,9,32,39,130,194,8,37,39,51,23,55,1,178,120,91,115,33,148,148,75,148,148,33,115,91,119,79,135,134,2,6,194,39,53,11,39,182,182,39,11,53,39,194,228,228,130,178,41,0,2,0,
|
||||
188,255,206,0,252,2,57,83,195,5,36,23,35,17,51,53,67,9,5,40,64,64,50,1,8,92,1,7,0,130,35,59,64,255,188,1,119,2,16,0,15,0,75,0,0,37,62,1,53,52,38,39,38,39,14,1,21,20,22,23,69,167,11,
|
||||
33,53,22,85,40,5,130,28,35,46,4,53,52,89,5,5,32,54,86,84,10,133,47,8,53,4,21,20,6,1,10,21,28,48,46,25,22,22,27,48,45,25,61,25,21,69,72,25,57,16,16,58,51,36,42,37,47,8,3,28,25,39,17,
|
||||
14,38,33,25,21,68,74,24,54,14,14,51,51,37,40,36,130,22,33,29,24,131,22,42,142,12,35,15,26,44,25,14,13,12,36,132,7,63,37,18,34,23,44,66,10,5,5,57,26,32,25,20,30,26,4,2,16,14,28,23,34,
|
||||
19,28,50,16,18,34,24,43,59,131,25,33,27,26,133,25,39,15,15,28,23,33,20,28,50,133,251,42,109,1,212,1,75,2,27,0,11,0,23,73,51,13,33,43,1,73,63,9,39,1,66,58,9,9,58,9,155,131,5,37,8,1,
|
||||
213,9,52,9,136,2,48,0,0,3,255,248,0,40,1,192,1,218,0,7,0,15,0,36,65,245,9,33,18,50,92,21,5,33,22,52,130,255,35,23,21,38,35,75,119,11,8,53,142,156,111,111,156,111,95,188,133,133,188,
|
||||
134,92,78,62,57,30,43,34,47,52,52,47,46,31,36,51,61,79,105,147,105,105,147,1,34,127,179,127,127,179,152,126,66,15,38,21,48,49,49,47,18,36,17,131,179,8,41,3,0,92,0,162,1,91,2,18,0,3,
|
||||
0,18,0,53,0,0,37,35,53,51,39,34,35,34,14,4,21,20,22,51,50,54,7,52,62,2,23,60,1,46,2,88,232,5,8,122,62,6,51,50,22,29,1,35,39,6,35,34,38,1,91,247,247,55,5,8,25,24,37,19,20,8,36,22,49,
|
||||
41,201,37,58,70,33,8,15,32,22,26,50,11,12,2,18,7,17,12,17,18,9,57,73,45,8,39,54,47,59,163,43,178,1,3,6,11,18,13,24,24,61,16,33,43,14,7,4,8,10,22,14,11,11,6,6,44,1,6,2,6,2,3,1,57,64,
|
||||
159,38,45,44,0,2,0,50,0,49,1,134,1,112,0,6,0,13,0,0,1,21,7,23,21,39,53,55,133,5,50,1,134,112,112,174,7,111,111,173,173,1,112,67,93,93,66,145,28,79,132,5,35,146,0,0,4,65,59,8,56,9,0,
|
||||
27,0,35,0,43,0,0,19,22,62,2,53,52,38,43,1,23,30,1,23,35,38,39,130,9,32,21,130,224,36,50,21,20,14,1,67,78,6,65,88,7,54,175,21,36,27,15,29,21,49,86,14,25,46,52,30,17,21,24,27,47,92,103,
|
||||
34,147,65,89,10,53,1,13,1,2,6,18,15,19,20,102,5,33,72,44,26,33,103,242,74,21,32,172,65,94,11,130,172,41,0,109,1,183,1,75,1,235,0,3,130,12,130,106,38,1,74,220,220,1,183,51,66,31,5,45,
|
||||
101,1,50,1,82,2,16,0,7,0,15,0,0,18,93,253,14,56,190,59,42,42,59,41,22,98,69,69,98,69,1,94,39,55,39,39,55,138,65,91,65,65,91,133,59,40,24,255,255,1,159,1,151,0,11,131,59,92,65,11,56,
|
||||
19,33,53,33,251,164,164,62,165,165,62,164,254,121,1,135,1,36,59,115,115,59,114,254,105,87,43,5,40,115,1,133,1,69,2,173,0,24,130,143,130,245,37,7,51,21,35,53,54,85,161,5,8,47,34,6,15,
|
||||
1,53,54,51,50,22,1,66,17,62,70,152,210,77,32,42,37,28,17,42,12,13,39,51,57,58,2,94,20,33,64,61,39,38,72,29,40,36,18,25,11,6,6,41,20,130,197,32,1,130,223,38,130,1,75,2,176,0,39,131,
|
||||
79,32,6,88,180,10,91,20,23,8,51,7,22,1,75,68,55,21,49,15,14,50,42,26,48,43,31,31,31,29,36,30,27,21,44,12,12,47,44,49,63,33,30,71,1,214,37,47,7,4,4,42,18,26,25,25,27,38,22,21,18,22,
|
||||
8,130,13,38,13,42,33,28,29,7,13,130,252,39,1,0,131,1,181,1,53,2,79,123,5,41,51,7,35,235,73,120,56,2,57,131,130,26,51,0,1,0,37,255,107,1,146,1,132,0,36,0,0,37,50,54,63,1,21,133,147,
|
||||
33,14,4,130,154,36,39,21,35,17,51,66,199,5,8,63,53,55,51,16,21,20,1,120,7,12,4,3,27,29,19,26,4,3,1,4,16,22,42,27,26,47,11,60,64,45,37,43,59,3,65,49,4,2,2,52,15,26,13,13,2,7,18,14,11,
|
||||
28,26,192,2,24,241,48,53,53,38,251,254,226,24,29,130,108,42,1,0,48,255,185,1,136,2,7,0,16,76,95,7,47,16,21,6,34,47,1,17,34,38,52,54,216,175,52,70,1,130,60,8,34,69,99,99,2,6,253,182,
|
||||
2,32,253,229,5,2,1,1,1,39,85,121,85,0,0,1,0,159,0,198,1,25,1,63,0,7,0,0,66,114,7,39,195,50,35,35,50,35,1,63,130,4,33,35,50,131,35,36,143,255,119,1,41,130,43,130,95,35,33,22,21,20,65,
|
||||
92,8,52,39,48,58,1,1,0,40,91,14,31,8,8,24,27,91,73,21,22,41,37,59,130,173,34,46,11,94,132,151,40,114,1,132,1,70,2,167,0,10,131,151,37,21,35,53,51,53,7,130,239,56,250,75,204,76,83,85,
|
||||
51,1,171,38,38,212,14,40,13,0,3,0,83,0,162,1,101,2,16,130,9,37,13,0,21,0,0,37,130,41,8,47,2,34,6,21,20,22,50,54,53,52,22,32,53,52,54,50,22,21,1,86,249,249,88,69,46,45,71,45,56,254,
|
||||
239,73,127,73,163,43,1,25,47,54,54,49,49,54,54,197,143,71,130,0,130,114,67,163,15,33,55,21,130,112,35,39,53,51,23,132,7,48,223,173,111,111,166,174,174,112,112,222,28,145,66,93,93,67,
|
||||
146,132,6,41,0,4,0,19,255,162,1,165,2,64,130,127,36,6,0,17,0,28,130,242,38,23,5,39,23,51,53,55,70,111,8,33,55,3,130,72,32,51,131,14,8,44,53,51,1,155,9,254,120,9,198,102,51,43,43,50,
|
||||
144,134,187,82,87,48,75,203,75,1,47,37,91,37,203,144,43,188,37,65,65,42,183,1,86,14,39,13,252,39,39,130,81,137,91,34,28,0,39,133,89,32,5,66,236,15,34,39,54,51,130,224,34,20,6,1,143,
|
||||
100,34,1,73,86,66,254,7,42,41,13,12,1,39,51,57,59,28,254,252,138,113,52,190,77,39,39,71,30,39,36,19,25,12,6,6,42,19,51,27,23,45,1,226,134,123,34,4,0,18,132,215,32,70,134,215,32,56,
|
||||
133,125,34,23,51,39,138,215,33,39,20,67,43,10,67,42,26,132,243,34,202,102,1,130,244,8,32,49,145,134,45,72,55,21,48,13,13,41,46,36,42,38,34,33,30,31,37,33,25,24,45,10,10,46,44,50,62,
|
||||
33,30,72,65,11,13,8,68,168,36,47,7,4,4,41,18,29,47,28,37,23,21,20,20,8,4,4,42,12,41,32,29,29,8,14,0,0,2,0,73,255,247,1,111,2,27,0,30,0,38,0,0,55,50,54,63,1,21,14,2,35,34,38,53,52,62,
|
||||
4,61,1,51,21,20,14,3,21,20,22,73,68,7,8,56,235,29,66,18,19,7,24,69,34,82,78,19,29,34,29,19,71,26,37,38,26,47,71,44,32,32,44,32,48,24,11,12,65,5,12,21,65,54,24,43,30,30,24,31,17,69,
|
||||
61,30,48,34,31,39,21,31,36,1,129,91,1,6,45,3,0,5,0,0,1,179,2,131,0,3,0,6,0,130,128,36,1,35,39,51,3,90,85,9,37,1,9,56,84,68,52,90,90,9,46,2,38,92,254,61,1,10,61,253,250,135,135,2,6,
|
||||
0,130,53,143,63,34,7,35,55,139,63,36,59,84,56,72,106,132,63,39,40,193,41,77,169,2,130,92,140,64,36,3,0,5,255,255,132,127,32,6,79,77,5,32,19,130,63,34,51,23,35,138,66,38,220,61,51,78,
|
||||
69,78,51,90,223,5,133,68,33,101,62,130,69,32,151,138,134,131,135,33,255,254,130,71,61,123,0,20,0,23,0,31,0,0,19,34,6,21,35,52,54,51,50,22,51,50,54,53,55,51,20,6,35,34,38,138,85,49,
|
||||
169,12,12,47,36,34,26,62,15,11,13,1,46,34,36,28,58,45,138,164,45,81,19,16,33,43,34,17,9,8,25,51,35,254,109,139,103,32,4,136,175,38,2,0,10,0,22,0,34,91,131,12,81,53,11,72,74,11,138,
|
||||
187,32,147,72,84,9,33,9,190,136,89,32,56,72,93,13,32,0,136,207,38,149,0,2,0,14,0,30,132,101,52,39,20,22,23,51,62,1,53,52,38,34,6,23,19,35,39,35,7,35,19,38,68,11,5,32,20,130,97,52,56,
|
||||
18,16,44,16,19,33,47,34,112,159,77,40,193,41,77,159,47,60,84,60,130,98,55,110,17,26,6,6,26,17,21,31,31,101,254,25,135,135,1,231,28,51,40,55,55,40,51,130,89,38,2,255,255,1,182,2,7,130,
|
||||
109,32,19,130,97,40,17,35,3,55,21,51,21,35,53,131,88,8,40,37,7,35,23,55,7,235,37,75,186,128,202,127,37,68,150,1,23,1,122,1,111,1,190,1,13,254,244,55,188,59,134,133,2,5,2,61,153,1,60,
|
||||
0,78,87,5,38,119,1,137,2,16,0,40,130,12,91,224,8,49,55,21,6,7,22,21,20,6,35,34,39,53,22,51,50,53,52,39,88,3,6,8,66,23,21,38,1,8,38,57,32,14,25,66,50,77,51,37,56,33,45,38,45,25,24,31,
|
||||
46,26,54,81,48,23,112,104,77,51,51,1,213,32,60,74,46,62,91,59,46,73,21,5,36,32,31,30,9,45,11,31,22,32,3,42,74,93,56,117,151,32,71,45,130,187,38,52,0,3,1,132,2,135,71,103,5,8,41,55,
|
||||
33,21,33,17,33,21,35,31,1,21,35,19,35,39,51,127,1,4,254,178,1,71,253,1,241,242,142,57,84,68,63,59,2,6,59,153,1,59,1,48,93,130,175,36,2,0,52,0,4,150,59,34,7,35,55,138,59,36,173,84,56,
|
||||
72,64,135,59,33,140,93,130,60,135,59,32,136,130,119,34,18,0,0,140,119,66,185,5,138,62,38,86,61,52,78,70,78,52,136,65,33,110,62,131,66,33,0,3,130,127,32,0,130,127,32,133,130,67,34,23,
|
||||
0,35,74,129,25,32,3,134,213,35,23,51,21,35,74,141,11,33,9,58,137,222,39,2,63,8,52,9,9,52,8,133,5,33,253,252,132,173,42,59,0,2,0,66,255,254,1,118,2,131,65,31,5,8,49,1,35,17,23,21,33,
|
||||
53,51,17,35,53,33,39,35,39,51,1,117,115,115,254,206,116,116,1,50,106,56,84,68,1,202,254,111,1,57,59,1,144,59,33,92,0,0,0,2,0,66,0,3,130,59,65,91,6,130,59,32,51,132,59,32,39,130,59,
|
||||
130,227,56,1,117,116,116,254,206,115,115,1,50,60,84,56,72,1,207,254,112,59,57,1,145,1,59,125,65,31,5,133,59,65,31,6,143,59,34,51,23,35,137,62,32,148,65,30,5,137,65,32,95,65,31,7,137,
|
||||
187,65,31,28,34,23,35,17,131,153,32,55,131,213,65,31,12,32,188,135,161,33,2,61,67,88,11,32,115,132,170,34,1,145,59,131,227,45,17,0,4,1,167,2,11,0,18,0,37,0,0,55,92,29,5,8,79,43,1,21,
|
||||
51,21,35,21,50,19,50,30,3,20,14,3,43,1,53,35,53,51,53,50,200,19,36,42,30,20,20,30,42,36,19,62,99,99,62,1,31,56,61,45,29,29,45,61,56,30,139,46,46,138,62,9,27,42,75,98,75,42,27,8,162,
|
||||
53,188,1,205,12,35,55,95,125,96,54,35,11,245,53,220,131,103,42,42,0,0,1,142,2,130,0,20,0,30,68,149,22,36,23,51,17,35,3,130,2,33,51,19,68,148,16,41,140,72,95,186,71,4,98,186,2,88,68,
|
||||
145,10,32,82,92,232,5,37,2,6,254,90,0,3,92,235,6,38,135,0,5,0,9,0,29,92,237,7,35,55,35,39,51,92,241,16,37,238,57,84,68,3,33,92,245,5,34,29,28,34,133,8,42,31,2,17,253,234,2,22,25,93,
|
||||
253,175,92,247,19,135,95,32,136,130,95,32,12,92,157,5,36,16,35,34,16,55,66,235,5,32,2,93,84,15,32,184,65,210,5,32,77,150,101,37,88,62,93,93,254,11,151,103,42,251,1,149,2,129,0,20,0,
|
||||
26,0,46,65,41,14,33,55,53,69,191,5,33,23,50,93,202,16,38,169,11,13,47,36,35,25,69,199,6,39,35,29,58,34,184,184,184,168,145,127,32,87,65,64,10,32,70,131,241,44,254,37,8,26,44,78,105,
|
||||
78,44,27,7,7,27,132,8,36,26,0,0,0,4,65,79,6,131,239,36,17,0,29,0,49,65,81,7,32,37,87,16,10,69,218,11,65,101,16,33,1,30,69,225,10,32,19,145,136,32,17,131,124,32,49,66,150,11,33,253,
|
||||
244,65,17,17,8,32,1,0,46,0,65,1,137,1,137,0,11,0,0,1,7,23,7,39,7,39,55,39,55,23,55,1,137,129,129,45,128,129,45,130,5,38,129,128,1,94,121,121,42,135,2,47,0,3,0,1,255,234,1,183,2,34,
|
||||
0,10,0,21,0,39,103,247,10,46,39,20,23,55,38,35,34,14,3,37,7,22,21,16,35,80,146,5,51,53,16,51,50,23,55,220,17,27,30,20,13,7,184,26,49,7,185,26,59,132,12,40,1,70,65,30,184,83,46,54,36,
|
||||
133,6,32,54,131,157,54,53,56,42,248,58,208,56,42,249,58,8,26,44,78,205,88,65,105,254,245,56,72,25,130,7,48,1,11,56,72,0,0,2,0,46,255,246,1,138,2,131,0,17,130,123,40,0,1,51,17,20,35,
|
||||
34,53,17,130,6,8,44,22,51,50,62,2,53,3,35,39,51,1,62,75,170,176,75,39,61,30,40,19,7,43,57,84,69,2,6,254,160,176,189,1,83,254,160,67,52,18,33,36,25,1,135,92,161,71,34,7,35,55,139,71,
|
||||
35,12,84,57,72,144,71,35,227,92,92,0,130,0,139,147,33,24,0,146,147,66,196,5,139,78,32,98,66,191,5,139,81,33,17,34,130,153,33,198,62,130,82,34,3,0,47,136,227,34,29,0,41,146,81,32,19,
|
||||
66,36,22,44,1,62,76,171,176,75,40,61,30,39,19,7,5,66,30,10,144,103,32,158,72,7,15,32,2,72,111,6,35,130,0,8,0,86,29,5,38,21,35,55,3,51,23,19,130,187,44,1,98,80,177,75,1,177,79,135,90,
|
||||
84,57,73,130,74,39,227,233,234,1,28,229,1,97,130,170,41,0,2,0,42,255,255,1,142,2,6,130,55,32,21,99,245,10,8,41,55,50,22,21,20,43,1,21,35,17,51,21,50,210,49,61,63,47,93,103,83,95,178,
|
||||
103,75,75,103,186,43,48,47,42,180,240,75,74,150,127,2,6,92,0,130,222,130,67,32,242,130,67,8,127,28,0,48,0,0,19,20,30,3,21,20,14,1,38,39,53,22,51,50,54,53,52,46,3,53,52,62,2,63,1,38,
|
||||
54,46,2,35,34,6,21,17,35,17,52,54,51,50,21,34,6,234,34,48,48,33,51,78,88,38,49,51,41,45,33,47,47,33,24,35,34,12,12,1,3,10,14,38,27,46,41,68,73,82,155,47,72,1,50,20,33,27,32,53,35,43,
|
||||
57,20,5,16,56,21,36,29,24,37,25,27,45,30,28,44,24,15,2,2,1,15,23,22,16,48,50,254,123,1,133,77,74,152,44,130,138,41,0,3,0,38,255,245,1,146,2,69,130,9,34,18,0,61,130,156,49,35,39,51,
|
||||
19,50,62,2,39,48,42,1,35,14,1,21,20,22,55,130,3,50,31,1,35,38,39,14,1,35,34,38,53,52,54,59,1,60,2,46,5,81,15,9,8,99,1,12,57,118,72,24,36,52,26,10,1,36,47,11,60,52,51,225,10,5,5,68,
|
||||
9,7,21,76,38,65,80,91,91,92,2,6,8,15,20,30,18,38,71,16,17,3,25,11,24,17,24,26,13,168,1,194,131,253,230,29,47,50,26,2,32,44,38,36,183,116,25,55,15,15,22,37,32,37,64,60,62,70,1,15,9,
|
||||
18,13,16,11,10,5,18,10,9,63,1,9,3,8,3,4,2,149,171,35,7,35,55,3,131,171,33,42,2,167,170,37,84,118,57,103,80,37,131,170,33,1,35,167,171,34,2,69,131,176,172,65,87,9,39,6,0,21,0,64,0,0,
|
||||
19,130,171,34,51,23,35,132,174,65,90,41,39,220,66,52,90,56,90,52,97,65,92,45,38,2,26,88,131,131,254,105,65,94,20,33,63,69,65,94,20,135,175,46,51,0,24,0,39,0,82,0,0,1,34,46,2,35,34,
|
||||
75,234,5,42,30,1,51,50,54,61,1,51,20,14,2,174,191,53,1,13,21,31,16,23,11,26,45,36,37,21,34,30,13,12,13,46,5,13,30,101,173,205,50,1,209,17,20,17,54,43,55,27,26,26,13,14,15,29,33,21,
|
||||
254,90,148,217,66,56,24,32,4,66,227,6,40,29,0,11,0,23,0,38,0,81,74,25,25,32,19,66,77,45,32,63,68,115,10,32,6,66,85,46,33,1,214,68,147,11,33,254,85,181,211,52,114,0,7,0,15,0,58,0,73,
|
||||
0,0,18,34,6,20,22,50,54,52,6,34,88,7,5,32,19,67,183,31,67,58,12,44,240,46,33,33,46,33,14,84,60,60,84,60,63,67,191,33,32,194,139,237,46,2,70,31,44,31,31,44,118,56,80,56,56,80,254,249,
|
||||
67,204,32,33,254,155,136,236,67,215,5,55,5,255,245,1,179,1,143,0,8,0,19,0,89,0,0,1,34,6,23,51,54,39,46,1,130,161,33,1,39,85,233,5,40,37,21,35,28,2,30,5,51,22,79,184,7,34,46,2,47,96,
|
||||
42,8,32,59,113,200,6,83,206,5,8,164,30,2,31,1,62,4,51,50,22,23,30,1,21,1,56,31,31,3,121,1,2,3,27,217,26,26,14,1,28,53,44,37,1,75,182,2,4,6,10,14,21,12,34,52,9,10,5,15,48,25,25,42,22,
|
||||
16,2,3,1,4,16,21,36,22,57,60,70,68,50,42,30,19,46,13,14,44,65,19,30,18,12,2,2,1,3,14,19,36,22,58,48,8,2,1,1,90,54,64,23,22,35,38,254,209,18,59,59,32,38,35,31,136,1,1,28,10,28,13,23,
|
||||
11,14,6,1,17,9,10,60,3,10,16,11,17,16,6,5,2,7,19,15,12,60,56,57,65,28,50,39,14,8,7,58,24,9,13,13,4,5,2,6,15,11,10,59,76,18,42,12,130,248,42,1,0,59,255,119,1,125,1,142,0,37,132,243,
|
||||
42,21,20,22,51,50,55,21,14,1,15,1,77,223,14,130,222,34,54,51,50,98,88,10,35,14,43,15,15,77,222,8,33,82,106,98,99,5,56,88,74,76,76,74,43,65,11,15,2,2,36,32,31,30,8,46,12,32,22,31,3,
|
||||
105,96,98,98,114,5,41,0,3,0,37,255,247,1,147,2,69,130,9,34,9,0,30,69,235,5,32,23,98,25,22,42,21,23,32,1,19,57,118,72,55,46,70,98,30,12,40,92,89,1,254,217,1,194,131,236,98,33,17,145,
|
||||
95,35,7,35,55,7,154,95,36,93,119,56,102,49,147,95,34,2,69,131,147,96,33,0,0,138,195,36,6,0,12,0,33,69,87,8,154,102,39,225,67,52,90,57,90,52,64,148,104,36,26,88,131,131,105,145,202,
|
||||
33,0,4,65,43,6,68,51,5,34,29,0,50,68,51,25,65,65,27,44,69,57,9,9,57,9,155,58,9,9,58,9,39,147,128,68,5,13,32,125,146,137,8,58,0,0,2,0,51,255,252,1,117,2,59,0,13,0,17,0,0,37,51,21,34,
|
||||
35,34,38,61,1,35,53,51,21,20,17,35,39,51,1,37,80,24,71,54,65,90,158,57,119,73,51,54,78,63,201,50,251,86,1,132,131,0,130,0,34,2,0,68,130,59,32,116,149,59,48,19,7,35,55,1,37,79,23,72,
|
||||
53,66,90,158,106,119,57,103,135,60,34,2,7,131,130,61,135,59,36,69,0,6,0,20,65,105,8,32,19,140,126,39,186,66,52,90,56,90,51,40,134,68,70,121,5,32,113,134,131,130,127,32,3,134,127,38,
|
||||
26,0,11,0,23,0,37,65,69,25,141,86,33,1,44,65,56,5,132,5,32,130,134,92,33,1,212,69,49,12,32,95,135,101,54,2,0,42,255,244,1,142,2,27,0,14,0,47,0,0,55,50,54,53,52,38,47,1,90,34,6,38,19,
|
||||
20,30,6,21,20,6,72,186,5,8,96,23,46,1,47,1,7,39,55,39,51,23,55,23,7,22,220,45,60,20,10,10,18,50,43,59,60,145,20,6,19,8,13,6,5,89,88,88,89,107,100,5,27,10,11,103,12,88,67,81,47,106,
|
||||
13,93,36,42,70,71,38,67,15,14,9,69,73,73,69,1,89,1,27,10,29,19,33,29,38,19,86,107,107,94,93,102,8,8,31,12,11,31,34,27,69,49,32,34,28,34,65,115,5,32,62,130,231,44,122,2,32,0,18,0,43,
|
||||
0,0,19,50,22,21,100,121,12,34,23,54,55,71,88,17,54,35,34,46,2,253,53,72,68,39,38,47,56,68,64,4,37,3,26,45,36,37,20,35,71,51,5,40,14,29,21,21,31,17,22,1,145,100,165,9,51,1,132,47,60,
|
||||
99,54,44,54,27,26,26,14,13,15,29,33,21,17,20,17,130,124,40,3,0,43,255,244,1,141,2,69,86,227,7,36,1,35,39,51,18,102,253,8,99,73,7,37,1,15,56,119,73,5,99,78,9,37,1,194,131,253,229,71,
|
||||
99,82,9,35,204,204,102,0,130,65,143,75,35,7,35,55,2,145,75,36,86,118,57,103,96,137,75,34,2,69,131,145,76,137,151,36,6,0,16,0,24,66,77,8,145,78,72,242,6,32,112,138,80,37,26,88,131,131,
|
||||
254,104,143,158,136,159,32,32,130,79,34,34,0,42,72,179,24,145,99,53,1,15,20,32,16,22,12,25,46,36,38,20,35,29,14,12,13,46,5,14,30,118,137,113,36,1,190,17,20,17,65,92,11,33,254,108,142,
|
||||
125,32,4,65,103,6,66,215,5,34,33,0,41,66,217,25,146,126,93,1,10,33,9,11,138,118,66,224,13,32,86,142,115,32,3,130,231,36,49,1,159,1,136,130,249,42,19,0,35,0,0,37,33,53,33,39,35,96,108,
|
||||
13,32,3,142,15,48,1,159,254,121,1,135,161,70,4,7,7,4,70,5,6,6,5,136,9,37,192,59,56,6,5,63,131,18,130,4,33,254,255,130,11,131,35,130,11,32,0,130,0,44,3,0,12,255,222,1,172,1,166,0,7,
|
||||
0,15,131,107,39,55,50,54,53,52,39,7,22,78,242,6,37,6,37,7,22,21,20,78,241,7,8,65,52,54,51,50,23,55,22,222,47,57,10,169,27,56,9,168,27,46,45,59,1,54,61,33,178,75,44,57,34,62,29,94,83,
|
||||
71,46,55,34,43,72,80,42,32,189,37,152,42,31,189,33,70,121,68,52,81,204,40,63,26,70,50,81,102,102,39,63,27,67,55,5,51,61,255,246,1,123,2,59,0,3,0,26,0,0,1,35,39,51,23,51,17,105,15,6,
|
||||
38,61,1,51,21,20,22,51,130,133,8,41,1,13,57,119,73,144,68,63,6,2,5,20,23,38,21,77,61,67,38,43,44,53,1,184,131,182,254,124,57,2,10,23,18,14,72,82,244,240,52,52,59,50,130,84,33,2,0,141,
|
||||
83,34,7,35,55,148,83,36,83,119,56,102,44,143,83,34,2,59,131,147,84,135,83,36,69,0,6,0,29,66,201,8,32,23,145,169,32,55,66,203,6,32,92,139,171,41,42,45,53,2,2,26,88,131,131,61,143,174,
|
||||
32,235,130,175,32,3,134,175,95,67,5,32,46,66,85,25,148,197,35,63,58,8,8,95,89,6,33,9,128,140,205,130,117,95,106,13,32,80,143,125,42,0,0,2,0,26,255,107,1,158,2,59,80,107,7,34,2,7,14,
|
||||
99,148,6,8,49,55,3,51,27,1,7,35,55,1,86,72,140,39,14,32,36,25,18,54,46,30,32,22,160,72,123,105,119,56,102,1,133,254,175,98,35,44,18,5,54,46,54,1,127,254,208,1,230,131,131,130,203,34,
|
||||
2,0,50,130,79,39,134,2,32,0,9,0,23,0,107,131,10,33,19,50,66,59,5,53,21,35,17,51,21,54,174,89,55,57,86,56,99,80,91,171,67,32,68,68,31,42,66,245,11,37,65,202,2,180,208,61,130,75,32,3,
|
||||
134,155,32,17,130,155,38,29,0,41,0,0,1,51,142,157,80,34,23,144,177,32,100,71,147,10,144,185,32,118,80,40,14,42,1,0,30,255,249,1,153,2,20,0,43,130,115,40,34,7,51,7,35,6,21,20,21,130,
|
||||
6,35,30,3,51,50,107,75,6,38,39,35,55,51,38,52,55,130,5,8,76,62,1,51,50,23,21,46,1,1,44,110,20,178,18,163,1,132,17,111,6,27,38,37,23,20,61,27,47,61,88,103,14,65,18,44,2,2,62,18,47,14,
|
||||
103,83,65,48,28,61,1,220,144,36,30,4,17,15,37,44,60,29,10,19,24,71,28,104,95,37,29,9,28,36,95,105,29,72,24,21,130,246,130,2,36,14,0,174,0,1,130,7,131,2,34,1,0,4,134,11,32,1,130,7,32,
|
||||
10,134,11,32,2,130,7,32,16,134,11,36,3,0,29,0,78,134,11,131,43,32,112,134,11,36,5,0,9,0,134,134,11,32,6,130,7,44,148,0,3,0,1,4,9,0,0,0,2,0,0,134,11,32,1,130,11,32,6,134,11,32,2,130,
|
||||
11,32,12,134,11,36,3,0,58,0,18,134,11,32,4,130,23,32,108,134,11,32,5,130,21,32,114,134,11,32,6,130,23,35,144,0,46,0,143,2,39,70,0,111,0,110,0,116,0,131,7,40,114,0,103,0,101,0,32,0,
|
||||
50,130,36,32,48,130,7,32,58,130,3,32,46,134,7,36,49,0,49,0,45,130,25,131,3,32,48,130,7,51,54,0,0,70,111,110,116,70,111,114,103,101,32,50,46,48,32,58,32,46,130,3,39,49,49,45,50,45,50,
|
||||
48,50,130,30,133,107,32,86,130,81,36,114,0,115,0,105,132,103,32,32,130,89,40,0,86,101,114,115,105,111,110,32,136,140,33,2,0,139,0,65,75,7,137,19,32,192,130,10,131,251,60,3,0,4,0,5,
|
||||
0,6,0,7,0,8,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,130,235,8,50,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0,31,0,32,0,33,0,34,0,35,0,36,0,37,0,38,0,39,0,40,0,41,
|
||||
0,42,0,43,0,44,130,211,36,46,0,47,0,48,130,221,9,48,50,0,51,0,52,0,53,0,54,0,55,0,56,0,57,0,58,0,59,0,60,0,61,0,62,0,63,0,64,0,65,0,66,0,67,0,68,0,69,0,70,0,71,0,72,0,73,0,74,0,75,
|
||||
0,76,0,77,0,78,0,79,0,80,0,81,0,82,0,83,0,84,0,85,0,86,0,87,0,88,0,89,0,90,0,91,0,92,0,93,0,94,1,2,0,96,0,97,1,3,0,163,0,132,0,133,0,189,0,150,0,232,0,134,0,142,0,139,0,157,0,169,0,
|
||||
138,1,4,0,131,0,147,0,242,0,243,0,141,0,151,0,136,0,195,0,222,0,241,0,158,0,170,0,245,0,244,0,246,0,162,0,173,0,201,0,199,0,174,0,98,0,99,0,144,0,100,0,203,0,101,0,200,0,202,0,207,
|
||||
0,204,0,205,0,206,0,233,0,102,0,211,0,209,0,175,0,103,0,240,0,145,0,214,0,212,0,213,0,104,0,235,0,237,0,137,0,106,0,105,0,107,0,109,0,108,0,110,0,160,0,111,0,113,0,112,0,114,0,115,
|
||||
0,117,0,116,0,118,0,119,0,234,0,120,0,122,0,121,0,123,0,125,0,124,0,184,0,161,0,127,0,126,0,128,0,129,0,236,0,238,0,186,1,5,11,118,101,114,116,105,99,97,108,98,97,114,7,117,110,105,
|
||||
48,48,56,53,9,111,130,20,42,115,99,111,114,101,4,69,117,114,111,0,132,0,38,1,255,255,0,2,0,1,130,11,32,12,130,3,32,22,130,3,131,13,32,98,130,183,34,1,0,4,132,13,130,4,130,2,32,1,130,
|
||||
3,36,0,229,13,183,147,132,7,42,175,187,66,0,0,0,0,229,178,59,232,5,250,48,120,202,241,
|
||||
};
|
||||
|
||||
static const char* GetDefaultCompressedFontDataProggyForever(int* out_size)
|
||||
{
|
||||
*out_size = proggy_forever_minimal_ttf_compressed_size;
|
||||
return (const char*)proggy_forever_minimal_ttf_compressed_data;
|
||||
}
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+8
-15
@@ -153,7 +153,7 @@ struct ImGui_ImplFreeType_Data
|
||||
struct ImGui_ImplFreeType_FontSrcData
|
||||
{
|
||||
// Initialize from an external data buffer. Doesn't copy data, and you must ensure it stays valid up to this object lifetime.
|
||||
bool InitFont(FT_Library ft_library, ImFontConfig* src, ImGuiFreeTypeLoaderFlags extra_user_flags);
|
||||
bool InitFont(FT_Library ft_library, const ImFontConfig* src, ImGuiFreeTypeLoaderFlags extra_user_flags);
|
||||
void CloseFont();
|
||||
ImGui_ImplFreeType_FontSrcData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
~ImGui_ImplFreeType_FontSrcData() { CloseFont(); }
|
||||
@@ -172,9 +172,9 @@ struct ImGui_ImplFreeType_FontSrcBakedData
|
||||
ImGui_ImplFreeType_FontSrcBakedData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
bool ImGui_ImplFreeType_FontSrcData::InitFont(FT_Library ft_library, ImFontConfig* src, ImGuiFreeTypeLoaderFlags extra_font_loader_flags)
|
||||
bool ImGui_ImplFreeType_FontSrcData::InitFont(FT_Library ft_library, const ImFontConfig* src, ImGuiFreeTypeLoaderFlags extra_font_loader_flags)
|
||||
{
|
||||
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)src->FontData, (FT_Long)src->FontDataSize, (FT_Long)src->FontNo, &FtFace);
|
||||
FT_Error error = FT_New_Memory_Face(ft_library, (const FT_Byte*)src->FontData, (FT_Long)src->FontDataSize, (FT_Long)src->FontNo, &FtFace);
|
||||
if (error != 0)
|
||||
return false;
|
||||
error = FT_Select_Charmap(FtFace, FT_ENCODING_UNICODE);
|
||||
@@ -187,12 +187,8 @@ bool ImGui_ImplFreeType_FontSrcData::InitFont(FT_Library ft_library, ImFontConfi
|
||||
LoadFlags = 0;
|
||||
if ((UserFlags & ImGuiFreeTypeLoaderFlags_Bitmap) == 0)
|
||||
LoadFlags |= FT_LOAD_NO_BITMAP;
|
||||
|
||||
if (UserFlags & ImGuiFreeTypeLoaderFlags_NoHinting)
|
||||
LoadFlags |= FT_LOAD_NO_HINTING;
|
||||
else
|
||||
src->PixelSnapH = true; // FIXME: A bit weird to do this this way.
|
||||
|
||||
if (UserFlags & ImGuiFreeTypeLoaderFlags_NoAutoHint)
|
||||
LoadFlags |= FT_LOAD_NO_AUTOHINT;
|
||||
if (UserFlags & ImGuiFreeTypeLoaderFlags_ForceAutoHint)
|
||||
@@ -424,6 +420,7 @@ static bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* s
|
||||
float size = baked->Size;
|
||||
if (src->MergeMode && src->SizePixels != 0.0f)
|
||||
size *= (src->SizePixels / baked->OwnerFont->Sources[0]->SizePixels);
|
||||
size *= src->ExtraSizeScale;
|
||||
|
||||
ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData;
|
||||
bd_font_data->BakedLastActivated = baked;
|
||||
@@ -442,7 +439,7 @@ static bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* s
|
||||
// (FT_Set_Pixel_Sizes() essentially calls FT_Request_Size() with FT_SIZE_REQUEST_TYPE_NOMINAL)
|
||||
const float rasterizer_density = src->RasterizerDensity * baked->RasterizerDensity;
|
||||
FT_Size_RequestRec req;
|
||||
req.type = (bd_font_data->UserFlags & ImGuiFreeTypeLoaderFlags_Bitmap) ? FT_SIZE_REQUEST_TYPE_NOMINAL : FT_SIZE_REQUEST_TYPE_REAL_DIM;
|
||||
req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
|
||||
req.width = 0;
|
||||
req.height = (uint32_t)(size * 64 * rasterizer_density);
|
||||
req.horiResolution = 0;
|
||||
@@ -454,7 +451,7 @@ static bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* s
|
||||
{
|
||||
// Read metrics
|
||||
FT_Size_Metrics metrics = bd_baked_data->FtSize->metrics;
|
||||
const float scale = 1.0f / rasterizer_density;
|
||||
const float scale = 1.0f / (rasterizer_density * src->ExtraSizeScale);
|
||||
baked->Ascent = (float)FT_CEIL(metrics.ascender) * scale; // The pixel extents above the baseline in pixels (typically positive).
|
||||
baked->Descent = (float)FT_CEIL(metrics.descender) * scale; // The extents below the baseline in pixels (typically negative).
|
||||
//LineSpacing = (float)FT_CEIL(metrics.height) * scale; // The baseline-to-baseline distance. Note that it usually is larger than the sum of the ascender and descender taken as absolute values. There is also no guarantee that no glyphs extend above or below subsequent baselines when using this distance. Think of it as a value the designer of the font finds appropriate.
|
||||
@@ -541,12 +538,8 @@ static bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConf
|
||||
|
||||
const float ref_size = baked->OwnerFont->Sources[0]->SizePixels;
|
||||
const float offsets_scale = (ref_size != 0.0f) ? (baked->Size / ref_size) : 1.0f;
|
||||
float font_off_x = (src->GlyphOffset.x * offsets_scale);
|
||||
float font_off_y = (src->GlyphOffset.y * offsets_scale) + baked->Ascent;
|
||||
if (src->PixelSnapH) // Snap scaled offset. This is to mitigate backward compatibility issues for GlyphOffset, but a better design would be welcome.
|
||||
font_off_x = IM_ROUND(font_off_x);
|
||||
if (src->PixelSnapV)
|
||||
font_off_y = IM_ROUND(font_off_y);
|
||||
float font_off_x = ImFloor(src->GlyphOffset.x * offsets_scale + 0.5f); // Snap scaled offset.
|
||||
float font_off_y = ImFloor(src->GlyphOffset.y * offsets_scale + 0.5f) + baked->Ascent;
|
||||
float recip_h = 1.0f / rasterizer_density;
|
||||
float recip_v = 1.0f / rasterizer_density;
|
||||
|
||||
|
||||
Vendored
+95
-91
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.5
|
||||
// dear imgui, v1.92.6
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
@@ -240,6 +240,7 @@ Index of this file:
|
||||
#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*'
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow"
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion" // warning: conversion to 'xxxx' from 'xxxx' may change the sign of the result
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -335,7 +336,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
// - always performing the GetOrAddByKey() O(log N) query in g.Tables.Map[].
|
||||
const bool use_child_window = (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0;
|
||||
const ImVec2 avail_size = GetContentRegionAvail();
|
||||
const ImVec2 actual_outer_size = ImTrunc(CalcItemSize(outer_size, ImMax(avail_size.x, 1.0f), use_child_window ? ImMax(avail_size.y, 1.0f) : 0.0f));
|
||||
const ImVec2 actual_outer_size = ImTrunc(CalcItemSize(outer_size, ImMax(avail_size.x, IMGUI_WINDOW_HARD_MIN_SIZE), use_child_window ? ImMax(avail_size.y, IMGUI_WINDOW_HARD_MIN_SIZE) : 0.0f));
|
||||
const ImRect outer_rect(outer_window->DC.CursorPos, outer_window->DC.CursorPos + actual_outer_size);
|
||||
const bool outer_window_is_measuring_size = (outer_window->AutoFitFramesX > 0) || (outer_window->AutoFitFramesY > 0); // Doesn't apply to AlwaysAutoResize windows!
|
||||
if (use_child_window && IsClippedEx(outer_rect, 0) && !outer_window_is_measuring_size)
|
||||
@@ -564,9 +565,9 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
const int old_columns_count = table->Columns.size();
|
||||
if (old_columns_count != 0 && old_columns_count != columns_count)
|
||||
{
|
||||
// Attempt to preserve width on column count change (#4046)
|
||||
// Attempt to preserve width and other settings on column count/specs change (#4046)
|
||||
old_columns_to_preserve = table->Columns.Data;
|
||||
old_columns_raw_data = table->RawData;
|
||||
old_columns_raw_data = table->RawData; // Free at end of function
|
||||
table->RawData = NULL;
|
||||
}
|
||||
if (table->RawData == NULL)
|
||||
@@ -592,7 +593,6 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
ImGuiTableColumn* column = &table->Columns[n];
|
||||
if (old_columns_to_preserve && n < old_columns_count)
|
||||
{
|
||||
// FIXME: We don't attempt to preserve column order in this path.
|
||||
*column = old_columns_to_preserve[n];
|
||||
}
|
||||
else
|
||||
@@ -602,8 +602,9 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
column->WidthAuto = width_auto;
|
||||
column->IsPreserveWidthAuto = true; // Preserve WidthAuto when reinitializing a live table: not technically necessary but remove a visible flicker
|
||||
column->IsEnabled = column->IsUserEnabled = column->IsUserEnabledNextFrame = true;
|
||||
column->DisplayOrder = (ImGuiTableColumnIdx)n;
|
||||
}
|
||||
column->DisplayOrder = table->DisplayOrderToIndex[n] = (ImGuiTableColumnIdx)n;
|
||||
table->DisplayOrderToIndex[n] = column->DisplayOrder;
|
||||
}
|
||||
}
|
||||
if (old_columns_raw_data)
|
||||
@@ -698,7 +699,7 @@ void ImGui::TableBeginApplyRequests(ImGuiTable* table)
|
||||
}
|
||||
|
||||
// Handle reordering request
|
||||
// Note: we don't clear ReorderColumn after handling the request.
|
||||
// Note: we don't clear ReorderColumn after handling the request (FIXME: clarify why or add a test).
|
||||
if (table->InstanceCurrent == 0)
|
||||
{
|
||||
if (table->HeldHeaderColumn == -1 && table->ReorderColumn != -1)
|
||||
@@ -710,24 +711,12 @@ void ImGui::TableBeginApplyRequests(ImGuiTable* table)
|
||||
// In the configuration below, moving C to the right of E will lead to:
|
||||
// ... C [D] E ---> ... [D] E C (Column name/index)
|
||||
// ... 2 3 4 ... 2 3 4 (Display order)
|
||||
const int reorder_dir = table->ReorderColumnDir;
|
||||
IM_ASSERT(reorder_dir == -1 || reorder_dir == +1);
|
||||
IM_ASSERT(table->ReorderColumnDir == -1 || table->ReorderColumnDir == +1);
|
||||
IM_ASSERT(table->Flags & ImGuiTableFlags_Reorderable);
|
||||
ImGuiTableColumn* src_column = &table->Columns[table->ReorderColumn];
|
||||
ImGuiTableColumn* dst_column = &table->Columns[(reorder_dir == -1) ? src_column->PrevEnabledColumn : src_column->NextEnabledColumn];
|
||||
IM_UNUSED(dst_column);
|
||||
const int src_order = src_column->DisplayOrder;
|
||||
const int dst_order = dst_column->DisplayOrder;
|
||||
src_column->DisplayOrder = (ImGuiTableColumnIdx)dst_order;
|
||||
for (int order_n = src_order + reorder_dir; order_n != dst_order + reorder_dir; order_n += reorder_dir)
|
||||
table->Columns[table->DisplayOrderToIndex[order_n]].DisplayOrder -= (ImGuiTableColumnIdx)reorder_dir;
|
||||
IM_ASSERT(dst_column->DisplayOrder == dst_order - reorder_dir);
|
||||
|
||||
// Display order is stored in both columns->IndexDisplayOrder and table->DisplayOrder[]. Rebuild later from the former.
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
table->DisplayOrderToIndex[table->Columns[column_n].DisplayOrder] = (ImGuiTableColumnIdx)column_n;
|
||||
ImGuiTableColumn* dst_column = &table->Columns[(table->ReorderColumnDir < 0) ? src_column->PrevEnabledColumn : src_column->NextEnabledColumn];
|
||||
TableSetColumnDisplayOrder(table, table->ReorderColumn, dst_column->DisplayOrder);
|
||||
table->ReorderColumnDir = 0;
|
||||
table->IsSettingsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,6 +730,31 @@ void ImGui::TableBeginApplyRequests(ImGuiTable* table)
|
||||
}
|
||||
}
|
||||
|
||||
// Note that TableSetupScrollFreeze() enforce a display order range for frozen columns.
|
||||
// So reordering a column across the frozen column barrier is illegal and will be undone.
|
||||
void ImGui::TableSetColumnDisplayOrder(ImGuiTable* table, int column_n, int dst_order)
|
||||
{
|
||||
IM_ASSERT(column_n >= 0 && column_n < table->ColumnsCount);
|
||||
IM_ASSERT(dst_order >= 0 && dst_order < table->ColumnsCount);
|
||||
|
||||
ImGuiTableColumn* src_column = &table->Columns[column_n];
|
||||
const int src_order = src_column->DisplayOrder;
|
||||
if (src_order == dst_order)
|
||||
return;
|
||||
const int reorder_dir = (dst_order < src_order) ? -1 : +1;
|
||||
|
||||
src_column->DisplayOrder = (ImGuiTableColumnIdx)dst_order;
|
||||
for (int order_n = src_order + reorder_dir; order_n != dst_order + reorder_dir; order_n += reorder_dir)
|
||||
table->Columns[table->DisplayOrderToIndex[order_n]].DisplayOrder -= (ImGuiTableColumnIdx)reorder_dir;
|
||||
//IM_ASSERT(dst_column->DisplayOrder == dst_order - reorder_dir);
|
||||
|
||||
// Display order is stored in both columns->IndexDisplayOrder and table->DisplayOrder[]. Rebuild later from the former.
|
||||
// FIXME-OPT: If this is called multiple times we'd effectively have a O(N^2) thing going on.
|
||||
for (int n = 0; n < table->ColumnsCount; n++)
|
||||
table->DisplayOrderToIndex[table->Columns[n].DisplayOrder] = (ImGuiTableColumnIdx)n;
|
||||
table->IsSettingsDirty = true;
|
||||
}
|
||||
|
||||
// Adjust flags: default width mode + stretch columns are not allowed when auto extending
|
||||
static void TableSetupColumnFlags(ImGuiTable* table, ImGuiTableColumn* column, ImGuiTableColumnFlags flags_in)
|
||||
{
|
||||
@@ -1348,11 +1362,7 @@ void ImGui::EndTable()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "EndTable() call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "EndTable() call should only be done while in BeginTable() scope!");
|
||||
|
||||
// This assert would be very useful to catch a common error... unfortunately it would probably trigger in some
|
||||
// cases, and for consistency user may sometimes output empty tables (and still benefit from e.g. outer border)
|
||||
@@ -1383,7 +1393,7 @@ void ImGui::EndTable()
|
||||
inner_window->DC.PrevLineSize = temp_data->HostBackupPrevLineSize;
|
||||
inner_window->DC.CurrLineSize = temp_data->HostBackupCurrLineSize;
|
||||
inner_window->DC.CursorMaxPos = temp_data->HostBackupCursorMaxPos;
|
||||
const float inner_content_max_y = table->RowPosY2;
|
||||
const float inner_content_max_y = ImCeil(table->RowPosY2); // Rounding final position is important as we currently don't round row height ('Demo->Tables->Outer Size' demo uses non-integer heights)
|
||||
IM_ASSERT(table->RowPosY2 == inner_window->DC.CursorPos.y);
|
||||
if (inner_window != outer_window)
|
||||
inner_window->DC.CursorMaxPos.y = inner_content_max_y;
|
||||
@@ -1601,18 +1611,10 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
IM_ASSERT_USER_ERROR_RET(table->DeclColumnsCount < table->ColumnsCount, "TableSetupColumn(): called too many times!");
|
||||
IM_ASSERT_USER_ERROR_RET(table->IsLayoutLocked == false, "TableSetupColumn(): need to call before first row!");
|
||||
IM_ASSERT((flags & ImGuiTableColumnFlags_StatusMask_) == 0 && "Illegal to pass StatusMask values to TableSetupColumn()");
|
||||
if (table->DeclColumnsCount >= table->ColumnsCount)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table->DeclColumnsCount < table->ColumnsCount, "Called TableSetupColumn() too many times!");
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiTableColumn* column = &table->Columns[table->DeclColumnsCount];
|
||||
table->DeclColumnsCount++;
|
||||
@@ -1620,7 +1622,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
||||
// Assert when passing a width or weight if policy is entirely left to default, to avoid storing width into weight and vice-versa.
|
||||
// Give a grace to users of ImGuiTableFlags_ScrollX.
|
||||
if (table->IsDefaultSizingPolicy && (flags & ImGuiTableColumnFlags_WidthMask_) == 0 && (flags & ImGuiTableFlags_ScrollX) == 0)
|
||||
IM_ASSERT(init_width_or_weight <= 0.0f && "Can only specify width/weight if sizing policy is set explicitly in either Table or Column.");
|
||||
IM_ASSERT_USER_ERROR_RET(init_width_or_weight <= 0.0f, "TableSetupColumn(): can only specify width/weight if sizing policy is set explicitly in either Table or Column.");
|
||||
|
||||
// When passing a width automatically enforce WidthFixed policy
|
||||
// (whereas TableSetupColumnFlags would default to WidthAuto if table is not resizable)
|
||||
@@ -1662,12 +1664,8 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "TableSetupColumn(): need to call before first row!");
|
||||
IM_ASSERT(columns >= 0 && columns < IMGUI_TABLE_MAX_COLUMNS);
|
||||
IM_ASSERT(rows >= 0 && rows < 128); // Arbitrary limit
|
||||
|
||||
@@ -1743,11 +1741,7 @@ void ImGui::TableSetColumnEnabled(int column_n, bool enabled)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
IM_ASSERT(table->Flags & ImGuiTableFlags_Hideable); // See comments above
|
||||
if (column_n < 0)
|
||||
column_n = table->CurrentColumn;
|
||||
@@ -1825,12 +1819,8 @@ void ImGui::TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
IM_ASSERT(target != ImGuiTableBgTarget_None);
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (color == IM_COL32_DISABLE)
|
||||
color = 0;
|
||||
@@ -2128,11 +2118,7 @@ bool ImGui::TableSetColumnIndex(int column_n)
|
||||
{
|
||||
if (table->CurrentColumn != -1)
|
||||
TableEndCell(table);
|
||||
if ((column_n >= 0 && column_n < table->ColumnsCount) == false)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(column_n >= 0 && column_n < table->ColumnsCount, "TableSetColumnIndex() invalid column index!");
|
||||
return false;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RETV(column_n >= 0 && column_n < table->ColumnsCount, false, "TableSetColumnIndex() invalid column index!");
|
||||
TableBeginCell(table, column_n);
|
||||
}
|
||||
|
||||
@@ -2458,6 +2444,11 @@ void ImGui::TableUpdateColumnsWeightFromWidth(ImGuiTable* table)
|
||||
// - TableDrawBorders() [Internal]
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
|
||||
// FIXME: This could be abstracted and merged with PushColumnsBackground(), by creating a generic struct
|
||||
// with storage for backup cliprect + backup channel + storage for splitter pointer, new clip rect.
|
||||
// This would slightly simplify caller code.
|
||||
|
||||
// Bg2 is used by Selectable (and possibly other widgets) to render to the background.
|
||||
// Unlike our Bg0/1 channel which we uses for RowBg/CellBg/Borders and where we guarantee all shapes to be CPU-clipped, the Bg2 channel being widgets-facing will rely on regular ClipRect.
|
||||
void ImGui::TablePushBackgroundChannel()
|
||||
@@ -2619,7 +2610,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
||||
const int size_for_masks_bitarrays_one = (int)ImBitArrayGetStorageSizeInBytes(max_draw_channels);
|
||||
g.TempBuffer.reserve(size_for_masks_bitarrays_one * 5);
|
||||
memset(g.TempBuffer.Data, 0, size_for_masks_bitarrays_one * 5);
|
||||
for (int n = 0; n < IM_ARRAYSIZE(merge_groups); n++)
|
||||
for (int n = 0; n < IM_COUNTOF(merge_groups); n++)
|
||||
merge_groups[n].ChannelsMask = (ImBitArrayPtr)(void*)(g.TempBuffer.Data + (size_for_masks_bitarrays_one * n));
|
||||
ImBitArrayPtr remaining_mask = (ImBitArrayPtr)(void*)(g.TempBuffer.Data + (size_for_masks_bitarrays_one * 4));
|
||||
|
||||
@@ -2676,7 +2667,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
||||
// [DEBUG] Display merge groups
|
||||
#if 0
|
||||
if (g.IO.KeyShift)
|
||||
for (int merge_group_n = 0; merge_group_n < IM_ARRAYSIZE(merge_groups); merge_group_n++)
|
||||
for (int merge_group_n = 0; merge_group_n < IM_COUNTOF(merge_groups); merge_group_n++)
|
||||
{
|
||||
MergeGroup* merge_group = &merge_groups[merge_group_n];
|
||||
if (merge_group->ChannelsCount == 0)
|
||||
@@ -2704,7 +2695,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
||||
int remaining_count = splitter->_Count - (has_freeze_v ? LEADING_DRAW_CHANNELS + 1 : LEADING_DRAW_CHANNELS);
|
||||
//ImRect host_rect = (table->InnerWindow == table->OuterWindow) ? table->InnerClipRect : table->HostClipRect;
|
||||
ImRect host_rect = table->HostClipRect;
|
||||
for (int merge_group_n = 0; merge_group_n < IM_ARRAYSIZE(merge_groups); merge_group_n++)
|
||||
for (int merge_group_n = 0; merge_group_n < IM_COUNTOF(merge_groups); merge_group_n++)
|
||||
{
|
||||
if (int merge_channels_count = merge_groups[merge_group_n].ChannelsCount)
|
||||
{
|
||||
@@ -3113,11 +3104,7 @@ void ImGui::TableHeadersRow()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
|
||||
// Call layout if not already done. This is automatically done by TableNextRow: we do it here _only_ to make
|
||||
// it easier to debug-step in TableUpdateLayout(). Your own version of this function doesn't need this.
|
||||
@@ -3162,12 +3149,7 @@ void ImGui::TableHeader(const char* label)
|
||||
return;
|
||||
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
IM_ASSERT(table->CurrentColumn != -1);
|
||||
const int column_n = table->CurrentColumn;
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
@@ -3197,7 +3179,7 @@ void ImGui::TableHeader(const char* label)
|
||||
sort_arrow = true;
|
||||
if (column->SortOrder > 0)
|
||||
{
|
||||
ImFormatString(sort_order_suf, IM_ARRAYSIZE(sort_order_suf), "%d", column->SortOrder + 1);
|
||||
ImFormatString(sort_order_suf, IM_COUNTOF(sort_order_suf), "%d", column->SortOrder + 1);
|
||||
w_sort_text = g.Style.ItemInnerSpacing.x + CalcTextSize(sort_order_suf).x;
|
||||
}
|
||||
}
|
||||
@@ -3342,11 +3324,7 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImDrawList* draw_list = window->DrawList;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
IM_ASSERT(table->CurrentRow == -1 && "Must be first row");
|
||||
|
||||
if (max_label_width == 0.0f)
|
||||
@@ -3787,7 +3765,6 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
|
||||
|
||||
// Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn
|
||||
ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings();
|
||||
ImU64 display_order_mask = 0;
|
||||
for (int data_n = 0; data_n < settings->ColumnsCount; data_n++, column_settings++)
|
||||
{
|
||||
int column_n = column_settings->Index;
|
||||
@@ -3804,24 +3781,51 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
|
||||
}
|
||||
if (settings->SaveFlags & ImGuiTableFlags_Reorderable)
|
||||
column->DisplayOrder = column_settings->DisplayOrder;
|
||||
display_order_mask |= (ImU64)1 << column->DisplayOrder;
|
||||
if ((settings->SaveFlags & ImGuiTableFlags_Hideable) && column_settings->IsEnabled != -1)
|
||||
column->IsUserEnabled = column->IsUserEnabledNextFrame = column_settings->IsEnabled == 1;
|
||||
column->SortOrder = column_settings->SortOrder;
|
||||
column->SortDirection = column_settings->SortDirection;
|
||||
}
|
||||
|
||||
// Validate and fix invalid display order data
|
||||
const ImU64 expected_display_order_mask = (settings->ColumnsCount == 64) ? ~0 : ((ImU64)1 << settings->ColumnsCount) - 1;
|
||||
if (display_order_mask != expected_display_order_mask)
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
table->Columns[column_n].DisplayOrder = (ImGuiTableColumnIdx)column_n;
|
||||
|
||||
// Rebuild index
|
||||
// Fix display order and build index
|
||||
if (settings->SaveFlags & ImGuiTableFlags_Reorderable)
|
||||
TableFixDisplayOrder(table);
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
table->DisplayOrderToIndex[table->Columns[column_n].DisplayOrder] = (ImGuiTableColumnIdx)column_n;
|
||||
}
|
||||
|
||||
struct ImGuiTableFixDisplayOrderColumnData
|
||||
{
|
||||
ImGuiTableColumnIdx Idx;
|
||||
ImGuiTable* Table; // This is unfortunate but we don't have userdata in qsort api.
|
||||
};
|
||||
|
||||
// Sort by DisplayOrder and then Index
|
||||
static int IMGUI_CDECL TableFixDisplayOrderComparer(const void* lhs, const void* rhs)
|
||||
{
|
||||
const ImGuiTable* table = ((const ImGuiTableFixDisplayOrderColumnData*)lhs)->Table;
|
||||
const ImGuiTableColumnIdx lhs_idx = ((const ImGuiTableFixDisplayOrderColumnData*)lhs)->Idx;
|
||||
const ImGuiTableColumnIdx rhs_idx = ((const ImGuiTableFixDisplayOrderColumnData*)rhs)->Idx;
|
||||
const int order_delta = (table->Columns[lhs_idx].DisplayOrder - table->Columns[rhs_idx].DisplayOrder);
|
||||
return (order_delta > 0) ? +1 : (order_delta < 0) ? -1 : (lhs_idx > rhs_idx) ? +1 : -1;
|
||||
}
|
||||
|
||||
// Fix invalid display order data: compact values (0,1,3 -> 0,1,2); preserve relative order (0,3,1 -> 0,2,1); deduplicate (0,4,1,1 -> 0,3,1,2)
|
||||
void ImGui::TableFixDisplayOrder(ImGuiTable* table)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.TempBuffer.reserve((int)(sizeof(ImGuiTableFixDisplayOrderColumnData) * table->ColumnsCount)); // FIXME: Maybe wrap those two lines as a helper.
|
||||
ImGuiTableFixDisplayOrderColumnData* fdo_columns = (ImGuiTableFixDisplayOrderColumnData*)(void*)g.TempBuffer.Data;
|
||||
for (int n = 0; n < table->ColumnsCount; n++)
|
||||
{
|
||||
fdo_columns[n].Idx = (ImGuiTableColumnIdx)n;
|
||||
fdo_columns[n].Table = table;
|
||||
}
|
||||
ImQsort(fdo_columns, (size_t)table->ColumnsCount, sizeof(ImGuiTableFixDisplayOrderColumnData), TableFixDisplayOrderComparer);
|
||||
for (int n = 0; n < table->ColumnsCount; n++)
|
||||
table->Columns[fdo_columns[n].Idx].DisplayOrder = (ImGuiTableColumnIdx)n;
|
||||
}
|
||||
|
||||
static void TableSettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*)
|
||||
{
|
||||
ImGuiContext& g = *ctx;
|
||||
@@ -4063,7 +4067,7 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
|
||||
ImGuiTableColumn* column = &table->Columns[n];
|
||||
const char* name = TableGetColumnName(table, n);
|
||||
char buf[512];
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf),
|
||||
ImFormatString(buf, IM_COUNTOF(buf),
|
||||
"Column %d order %d '%s': offset %+.2f to %+.2f%s\n"
|
||||
"Enabled: %d, VisibleX/Y: %d/%d, RequestOutput: %d, SkipItems: %d, DrawChannels: %d,%d\n"
|
||||
"WidthGiven: %.1f, Request/Auto: %.1f/%.1f, StretchWeight: %.3f (%.1f%%)\n"
|
||||
|
||||
Vendored
+161
-134
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.5
|
||||
// dear imgui, v1.92.6
|
||||
// (widgets code)
|
||||
|
||||
/*
|
||||
@@ -92,6 +92,7 @@ Index of this file:
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion" // warning: conversion to 'xxxx' from 'xxxx' may change the sign of the result
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -134,7 +135,7 @@ static const ImU64 IM_U64_MAX = (2ULL * 9223372036854775807LL + 1);
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// For InputTextEx()
|
||||
static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard = false);
|
||||
static bool InputTextFilterCharacter(ImGuiContext* ctx, ImGuiInputTextState* state, unsigned int* p_char, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard = false);
|
||||
static ImVec2 InputTextCalcTextSize(ImGuiContext* ctx, const char* text_begin, const char* text_end_display, const char* text_end, const char** out_remaining = NULL, ImVec2* out_offset = NULL, ImDrawTextFlags flags = 0);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -836,11 +837,10 @@ bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg, ImGuiBut
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
// Cannot use zero-size for InvisibleButton(). Unlike Button() there is not way to fallback using the label size.
|
||||
IM_ASSERT(size_arg.x != 0.0f && size_arg.y != 0.0f);
|
||||
// Ensure zero-size fits to contents
|
||||
ImVec2 size = CalcItemSize(ImVec2(size_arg.x != 0.0f ? size_arg.x : -FLT_MIN, size_arg.y != 0.0f ? size_arg.y : -FLT_MIN), 0.0f, 0.0f);
|
||||
|
||||
const ImGuiID id = window->GetID(str_id);
|
||||
ImVec2 size = CalcItemSize(size_arg, 0.0f, 0.0f);
|
||||
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size);
|
||||
ItemSize(size);
|
||||
if (!ItemAdd(bb, id, NULL, (flags & ImGuiButtonFlags_EnableNav) ? ImGuiItemFlags_None : ImGuiItemFlags_NoNav))
|
||||
@@ -982,20 +982,7 @@ void ImGui::Scrollbar(ImGuiAxis axis)
|
||||
|
||||
// Calculate scrollbar bounding box
|
||||
ImRect bb = GetWindowScrollbarRect(window, axis);
|
||||
ImDrawFlags rounding_corners = ImDrawFlags_RoundCornersNone;
|
||||
if (axis == ImGuiAxis_X)
|
||||
{
|
||||
rounding_corners |= ImDrawFlags_RoundCornersBottomLeft;
|
||||
if (!window->ScrollbarY)
|
||||
rounding_corners |= ImDrawFlags_RoundCornersBottomRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar))
|
||||
rounding_corners |= ImDrawFlags_RoundCornersTopRight;
|
||||
if (!window->ScrollbarX)
|
||||
rounding_corners |= ImDrawFlags_RoundCornersBottomRight;
|
||||
}
|
||||
ImDrawFlags rounding_corners = CalcRoundingFlagsForRectInRect(bb, window->Rect(), g.Style.WindowBorderSize);
|
||||
float size_visible = window->InnerRect.Max[axis] - window->InnerRect.Min[axis];
|
||||
float size_contents = window->ContentSize[axis] + window->WindowPadding[axis] * 2.0f;
|
||||
ImS64 scroll = (ImS64)window->Scroll[axis];
|
||||
@@ -1037,6 +1024,8 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
|
||||
// V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar)
|
||||
const float scrollbar_size_v = (axis == ImGuiAxis_X) ? bb.GetWidth() : bb.GetHeight();
|
||||
if (scrollbar_size_v < 1.0f)
|
||||
return false;
|
||||
|
||||
// Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount)
|
||||
// But we maintain a minimum size in pixel to allow for the user to still aim inside.
|
||||
@@ -1129,11 +1118,15 @@ void ImGui::ImageWithBg(ImTextureRef tex_ref, const ImVec2& image_size, const Im
|
||||
return;
|
||||
|
||||
// Render
|
||||
if (g.Style.ImageBorderSize > 0.0f)
|
||||
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border), 0.0f, ImDrawFlags_None, g.Style.ImageBorderSize);
|
||||
float rounding = g.Style.ImageRounding;
|
||||
if (bg_col.w > 0.0f)
|
||||
window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, GetColorU32(bg_col));
|
||||
window->DrawList->AddImage(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
|
||||
window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, GetColorU32(bg_col), rounding);
|
||||
if (rounding > 0.0f)
|
||||
window->DrawList->AddImageRounded(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col), rounding);
|
||||
else
|
||||
window->DrawList->AddImage(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
|
||||
if (g.Style.ImageBorderSize > 0.0f)
|
||||
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border), rounding, ImDrawFlags_None, g.Style.ImageBorderSize);
|
||||
}
|
||||
|
||||
void ImGui::Image(ImTextureRef tex_ref, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1)
|
||||
@@ -1173,10 +1166,14 @@ bool ImGui::ImageButtonEx(ImGuiID id, ImTextureRef tex_ref, const ImVec2& image_
|
||||
// Render
|
||||
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
||||
RenderNavCursor(bb, id);
|
||||
RenderFrame(bb.Min, bb.Max, col, true, ImClamp((float)ImMin(padding.x, padding.y), 0.0f, g.Style.FrameRounding));
|
||||
RenderFrame(bb.Min, bb.Max, col, true, g.Style.FrameRounding);
|
||||
if (bg_col.w > 0.0f)
|
||||
window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, GetColorU32(bg_col));
|
||||
window->DrawList->AddImage(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
|
||||
float image_rounding = ImMax(g.Style.FrameRounding - ImMax(padding.x, padding.y), g.Style.ImageRounding);
|
||||
if (image_rounding > 0.0f)
|
||||
window->DrawList->AddImageRounded(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col), image_rounding);
|
||||
else
|
||||
window->DrawList->AddImage(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
|
||||
|
||||
return pressed;
|
||||
}
|
||||
@@ -1438,7 +1435,10 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over
|
||||
// Render
|
||||
RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
|
||||
bb.Expand(ImVec2(-style.FrameBorderSize, -style.FrameBorderSize));
|
||||
RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), fill_n0, fill_n1, style.FrameRounding);
|
||||
float fill_x0 = ImLerp(bb.Min.x, bb.Max.x, fill_n0);
|
||||
float fill_x1 = ImLerp(bb.Min.x, bb.Max.x, fill_n1);
|
||||
if (fill_x0 < fill_x1)
|
||||
RenderRectFilledInRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), fill_x0, fill_x1, style.FrameRounding);
|
||||
|
||||
// Default displaying the fraction as percentage string, but user can override it
|
||||
// Don't display text for indeterminate bars by default
|
||||
@@ -1447,14 +1447,14 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over
|
||||
{
|
||||
if (!overlay)
|
||||
{
|
||||
ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", fraction * 100 + 0.01f);
|
||||
ImFormatString(overlay_buf, IM_COUNTOF(overlay_buf), "%.0f%%", fraction * 100 + 0.01f);
|
||||
overlay = overlay_buf;
|
||||
}
|
||||
|
||||
ImVec2 overlay_size = CalcTextSize(overlay, NULL);
|
||||
if (overlay_size.x > 0.0f)
|
||||
{
|
||||
float text_x = is_indeterminate ? (bb.Min.x + bb.Max.x - overlay_size.x) * 0.5f : ImLerp(bb.Min.x, bb.Max.x, fill_n1) + style.ItemSpacing.x;
|
||||
float text_x = is_indeterminate ? (bb.Min.x + bb.Max.x - overlay_size.x) * 0.5f : fill_x1 + style.ItemSpacing.x;
|
||||
RenderTextClipped(ImVec2(ImClamp(text_x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImVec2(0.0f, 0.5f), &bb);
|
||||
}
|
||||
}
|
||||
@@ -1715,7 +1715,7 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end
|
||||
const float separator_thickness = style.SeparatorTextBorderSize;
|
||||
const ImVec2 min_size(label_size.x + extra_w + padding.x * 2.0f, ImMax(label_size.y + padding.y * 2.0f, separator_thickness));
|
||||
const ImRect bb(pos, ImVec2(window->WorkRect.Max.x, pos.y + min_size.y));
|
||||
const float text_baseline_y = ImTrunc((bb.GetHeight() - label_size.y) * style.SeparatorTextAlign.y + 0.99999f); //ImMax(padding.y, ImFloor((style.SeparatorTextSize - label_size.y) * 0.5f));
|
||||
const float text_baseline_y = ImTrunc((bb.GetHeight() - label_size.y) * style.SeparatorTextAlign.y + 0.99999f); //ImMax(padding.y, ImTrunc((style.SeparatorTextSize - label_size.y) * 0.5f));
|
||||
ItemSize(min_size, text_baseline_y);
|
||||
if (!ItemAdd(bb, id))
|
||||
return;
|
||||
@@ -1832,7 +1832,7 @@ static int IMGUI_CDECL ShrinkWidthItemComparer(const void* lhs, const void* rhs)
|
||||
const ImGuiShrinkWidthItem* b = (const ImGuiShrinkWidthItem*)rhs;
|
||||
if (int d = (int)(b->Width - a->Width))
|
||||
return d;
|
||||
return (b->Index - a->Index);
|
||||
return b->Index - a->Index;
|
||||
}
|
||||
|
||||
// Shrink excess width from a set of item, by removing width from the larger items first.
|
||||
@@ -2014,7 +2014,7 @@ bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags
|
||||
|
||||
// This is essentially a specialized version of BeginPopupEx()
|
||||
char name[16];
|
||||
ImFormatString(name, IM_ARRAYSIZE(name), "##Combo_%02d", g.BeginComboDepth); // Recycle windows based on depth
|
||||
ImFormatString(name, IM_COUNTOF(name), "##Combo_%02d", g.BeginComboDepth); // Recycle windows based on depth
|
||||
|
||||
// Set position given a custom constraint (peak into expected window size so we can position it)
|
||||
// FIXME: This might be easier to express with an hypothetical SetNextWindowPosConstraints() function?
|
||||
@@ -2049,8 +2049,12 @@ bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags
|
||||
void ImGui::EndCombo()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
EndPopup();
|
||||
g.BeginComboDepth--;
|
||||
char name[16];
|
||||
ImFormatString(name, IM_COUNTOF(name), "##Combo_%02d", g.BeginComboDepth); // FIXME: Move those to helpers?
|
||||
if (strcmp(g.CurrentWindow->Name, name) != 0)
|
||||
IM_ASSERT_USER_ERROR_RET(0, "Calling EndCombo() in wrong window!");
|
||||
EndPopup();
|
||||
}
|
||||
|
||||
// Call directly after the BeginCombo/EndCombo block. The preview is designed to only host non-interactive elements
|
||||
@@ -2235,6 +2239,11 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*old_getter)(void*
|
||||
// - RoundScalarWithFormat<>()
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
static const ImU32 GDefaultRgbaColorMarkers[4] =
|
||||
{
|
||||
IM_COL32(240,20,20,255), IM_COL32(20,240,20,255), IM_COL32(20,20,240,255), IM_COL32(140,140,140,255)
|
||||
};
|
||||
|
||||
static const ImGuiDataTypeInfo GDataTypeInfo[] =
|
||||
{
|
||||
{ sizeof(char), "S8", "%d", "%d" }, // ImGuiDataType_S8
|
||||
@@ -2255,7 +2264,7 @@ static const ImGuiDataTypeInfo GDataTypeInfo[] =
|
||||
{ sizeof(bool), "bool", "%d", "%d" }, // ImGuiDataType_Bool
|
||||
{ 0, "char*","%s", "%s" }, // ImGuiDataType_String
|
||||
};
|
||||
IM_STATIC_ASSERT(IM_ARRAYSIZE(GDataTypeInfo) == ImGuiDataType_COUNT);
|
||||
IM_STATIC_ASSERT(IM_COUNTOF(GDataTypeInfo) == ImGuiDataType_COUNT);
|
||||
|
||||
const ImGuiDataTypeInfo* ImGui::DataTypeGetInfo(ImGuiDataType data_type)
|
||||
{
|
||||
@@ -2364,7 +2373,7 @@ bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void
|
||||
if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double)
|
||||
format = type_info->ScanFmt;
|
||||
else
|
||||
format = ImParseFormatSanitizeForScanning(format, format_sanitized, IM_ARRAYSIZE(format_sanitized));
|
||||
format = ImParseFormatSanitizeForScanning(format, format_sanitized, IM_COUNTOF(format_sanitized));
|
||||
|
||||
// Small types need a 32-bit buffer to receive the result from scanf()
|
||||
int v32 = 0;
|
||||
@@ -2455,7 +2464,7 @@ static float GetMinimumStepAtDecimalPrecision(int decimal_precision)
|
||||
static const float min_steps[10] = { 1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f };
|
||||
if (decimal_precision < 0)
|
||||
return FLT_MIN;
|
||||
return (decimal_precision < IM_ARRAYSIZE(min_steps)) ? min_steps[decimal_precision] : ImPow(10.0f, (float)-decimal_precision);
|
||||
return (decimal_precision < IM_COUNTOF(min_steps)) ? min_steps[decimal_precision] : ImPow(10.0f, (float)-decimal_precision);
|
||||
}
|
||||
|
||||
template<typename TYPE>
|
||||
@@ -2469,12 +2478,12 @@ TYPE ImGui::RoundScalarWithFormatT(const char* format, ImGuiDataType data_type,
|
||||
|
||||
// Sanitize format
|
||||
char fmt_sanitized[32];
|
||||
ImParseFormatSanitizeForPrinting(fmt_start, fmt_sanitized, IM_ARRAYSIZE(fmt_sanitized));
|
||||
ImParseFormatSanitizeForPrinting(fmt_start, fmt_sanitized, IM_COUNTOF(fmt_sanitized));
|
||||
fmt_start = fmt_sanitized;
|
||||
|
||||
// Format value with our rounding, and read back
|
||||
char v_str[64];
|
||||
ImFormatString(v_str, IM_ARRAYSIZE(v_str), fmt_start, v);
|
||||
ImFormatString(v_str, IM_COUNTOF(v_str), fmt_start, v);
|
||||
const char* p = v_str;
|
||||
while (*p == ' ')
|
||||
p++;
|
||||
@@ -2683,6 +2692,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const float w = CalcItemWidth();
|
||||
const ImU32 color_marker = (g.NextItemData.HasFlags & ImGuiNextItemDataFlags_HasColorMarker) ? g.NextItemData.ColorMarker : 0;
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
||||
@@ -2751,7 +2761,10 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
// Draw frame
|
||||
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
||||
RenderNavCursor(frame_bb, id);
|
||||
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding);
|
||||
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, false, style.FrameRounding);
|
||||
if (color_marker != 0 && style.ColorMarkerSize > 0.0f)
|
||||
RenderColorComponentMarker(frame_bb, GetColorU32(color_marker), style.FrameRounding);
|
||||
RenderFrameBorder(frame_bb.Min, frame_bb.Max, g.Style.FrameRounding);
|
||||
|
||||
// Drag behavior
|
||||
const bool value_changed = DragBehavior(id, data_type, p_data, v_speed, p_min, p_max, format, flags);
|
||||
@@ -2760,7 +2773,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
|
||||
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
||||
char value_buf[64];
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, format);
|
||||
if (g.LogEnabled)
|
||||
LogSetNextTextDecoration("{", "}");
|
||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
||||
@@ -2789,6 +2802,8 @@ bool ImGui::DragScalarN(const char* label, ImGuiDataType data_type, void* p_data
|
||||
PushID(i);
|
||||
if (i > 0)
|
||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
if (flags & ImGuiSliderFlags_ColorMarkers)
|
||||
SetNextItemColorMarker(GDefaultRgbaColorMarkers[i]);
|
||||
value_changed |= DragScalar("", data_type, p_data, v_speed, p_min, p_max, format, flags);
|
||||
PopID();
|
||||
PopItemWidth();
|
||||
@@ -3287,6 +3302,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const float w = CalcItemWidth();
|
||||
const ImU32 color_marker = (g.NextItemData.HasFlags & ImGuiNextItemDataFlags_HasColorMarker) ? g.NextItemData.ColorMarker : 0;
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
||||
@@ -3337,7 +3353,10 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
// Draw frame
|
||||
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
||||
RenderNavCursor(frame_bb, id);
|
||||
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, g.Style.FrameRounding);
|
||||
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, false, style.FrameRounding);
|
||||
if (color_marker != 0 && style.ColorMarkerSize > 0.0f)
|
||||
RenderColorComponentMarker(frame_bb, GetColorU32(color_marker), style.FrameRounding);
|
||||
RenderFrameBorder(frame_bb.Min, frame_bb.Max, g.Style.FrameRounding);
|
||||
|
||||
// Slider behavior
|
||||
ImRect grab_bb;
|
||||
@@ -3351,7 +3370,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
|
||||
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
||||
char value_buf[64];
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, format);
|
||||
if (g.LogEnabled)
|
||||
LogSetNextTextDecoration("{", "}");
|
||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
||||
@@ -3381,6 +3400,8 @@ bool ImGui::SliderScalarN(const char* label, ImGuiDataType data_type, void* v, i
|
||||
PushID(i);
|
||||
if (i > 0)
|
||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
if (flags & ImGuiSliderFlags_ColorMarkers)
|
||||
SetNextItemColorMarker(GDefaultRgbaColorMarkers[i]);
|
||||
value_changed |= SliderScalar("", data_type, v, v_min, v_max, format, flags);
|
||||
PopID();
|
||||
PopItemWidth();
|
||||
@@ -3502,7 +3523,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
|
||||
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
||||
// For the vertical slider we allow centered text to overlap the frame padding
|
||||
char value_buf[64];
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, format);
|
||||
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.0f));
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||
@@ -3702,16 +3723,16 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG
|
||||
const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type);
|
||||
char fmt_buf[32];
|
||||
char data_buf[32];
|
||||
format = ImParseFormatTrimDecorations(format, fmt_buf, IM_ARRAYSIZE(fmt_buf));
|
||||
format = ImParseFormatTrimDecorations(format, fmt_buf, IM_COUNTOF(fmt_buf));
|
||||
if (format[0] == 0)
|
||||
format = type_info->PrintFmt;
|
||||
DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, p_data, format);
|
||||
DataTypeFormatString(data_buf, IM_COUNTOF(data_buf), data_type, p_data, format);
|
||||
ImStrTrimBlanks(data_buf);
|
||||
|
||||
ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | (ImGuiInputTextFlags)ImGuiInputTextFlags_LocalizeDecimalPoint;
|
||||
g.LastItemData.ItemFlags |= ImGuiItemFlags_NoMarkEdited; // Because TempInputText() uses ImGuiInputTextFlags_MergedItem it doesn't submit a new item, so we poke LastItemData.
|
||||
bool value_changed = false;
|
||||
if (TempInputText(bb, id, label, data_buf, IM_ARRAYSIZE(data_buf), flags))
|
||||
if (TempInputText(bb, id, label, data_buf, IM_COUNTOF(data_buf), flags))
|
||||
{
|
||||
// Backup old value
|
||||
size_t data_type_size = type_info->Size;
|
||||
@@ -3764,7 +3785,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
||||
if ((flags & ImGuiInputTextFlags_DisplayEmptyRefVal) && DataTypeCompare(data_type, p_data, p_data_default) == 0)
|
||||
buf[0] = 0;
|
||||
else
|
||||
DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format);
|
||||
DataTypeFormatString(buf, IM_COUNTOF(buf), data_type, p_data, format);
|
||||
|
||||
// Disable the MarkItemEdited() call in InputText but keep ImGuiItemStatusFlags_Edited.
|
||||
// We call MarkItemEdited() ourselves by comparing the actual data rather than the string.
|
||||
@@ -3774,7 +3795,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
||||
bool value_changed = false;
|
||||
if (p_step == NULL)
|
||||
{
|
||||
if (InputText(label, buf, IM_ARRAYSIZE(buf), flags))
|
||||
if (InputText(label, buf, IM_COUNTOF(buf), flags))
|
||||
value_changed = DataTypeApplyFromText(buf, data_type, p_data, format, (flags & ImGuiInputTextFlags_ParseEmptyRefVal) ? p_data_default : NULL);
|
||||
}
|
||||
else
|
||||
@@ -3784,7 +3805,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
||||
BeginGroup(); // The only purpose of the group here is to allow the caller to query item data e.g. IsItemActive()
|
||||
PushID(label);
|
||||
SetNextItemWidth(ImMax(1.0f, CalcItemWidth() - (button_size + style.ItemInnerSpacing.x) * 2));
|
||||
if (InputText("", buf, IM_ARRAYSIZE(buf), flags)) // PushId(label) + "" gives us the expected ID from outside point of view
|
||||
if (InputText("", buf, IM_COUNTOF(buf), flags)) // PushId(label) + "" gives us the expected ID from outside point of view
|
||||
value_changed = DataTypeApplyFromText(buf, data_type, p_data, format, (flags & ImGuiInputTextFlags_ParseEmptyRefVal) ? p_data_default : NULL);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Inputable);
|
||||
|
||||
@@ -4230,7 +4251,7 @@ static void stb_textedit_replace(ImGuiInputTextState* str, STB_TexteditState* st
|
||||
// We added an extra indirection where 'Stb' is heap-allocated, in order facilitate the work of bindings generators.
|
||||
ImGuiInputTextState::ImGuiInputTextState()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
Stb = IM_NEW(ImStbTexteditState);
|
||||
memset(Stb, 0, sizeof(*Stb));
|
||||
}
|
||||
@@ -4271,6 +4292,7 @@ void ImGuiInputTextState::ClearSelection() { Stb->select_start
|
||||
int ImGuiInputTextState::GetCursorPos() const { return Stb->cursor; }
|
||||
int ImGuiInputTextState::GetSelectionStart() const { return Stb->select_start; }
|
||||
int ImGuiInputTextState::GetSelectionEnd() const { return Stb->select_end; }
|
||||
void ImGuiInputTextState::SetSelection(int start, int end) { Stb->select_start = start; Stb->cursor = Stb->select_end = end; }
|
||||
float ImGuiInputTextState::GetPreferredOffsetX() const { return Stb->has_preferred_x ? Stb->preferred_x : -1; }
|
||||
void ImGuiInputTextState::SelectAll() { Stb->select_start = 0; Stb->cursor = Stb->select_end = TextLen; Stb->has_preferred_x = 0; }
|
||||
void ImGuiInputTextState::ReloadUserBufAndSelectAll() { WantReloadUserBuf = true; ReloadSelectionStart = 0; ReloadSelectionEnd = INT_MAX; }
|
||||
@@ -4279,7 +4301,7 @@ void ImGuiInputTextState::ReloadUserBufAndMoveToEnd() { WantReloadUserBuf
|
||||
|
||||
ImGuiInputTextCallbackData::ImGuiInputTextCallbackData()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
// Public API to manipulate UTF-8 text from within a callback.
|
||||
@@ -4375,9 +4397,10 @@ void ImGui::PopPasswordFont()
|
||||
}
|
||||
|
||||
// Return false to discard a character.
|
||||
static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard)
|
||||
static bool InputTextFilterCharacter(ImGuiContext* ctx, ImGuiInputTextState* state, unsigned int* p_char, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard)
|
||||
{
|
||||
unsigned int c = *p_char;
|
||||
ImGuiInputTextFlags flags = state->Flags;
|
||||
|
||||
// Filter non-printable (NB: isprint is unreliable! see #2467)
|
||||
bool apply_named_filters = true;
|
||||
@@ -4467,9 +4490,11 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiInputTextCallbackData callback_data;
|
||||
callback_data.Ctx = &g;
|
||||
callback_data.ID = state->ID;
|
||||
callback_data.Flags = flags;
|
||||
callback_data.EventFlag = ImGuiInputTextFlags_CallbackCharFilter;
|
||||
callback_data.EventChar = (ImWchar)c;
|
||||
callback_data.Flags = flags;
|
||||
callback_data.EventActivated = (g.ActiveId == state->ID && g.ActiveIdIsJustActivated);
|
||||
callback_data.UserData = user_data;
|
||||
if (callback(&callback_data) != 0)
|
||||
return false;
|
||||
@@ -4826,6 +4851,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
SetActiveID(id, window);
|
||||
SetFocusID(id, window);
|
||||
FocusWindow(window);
|
||||
if (input_requested_by_nav)
|
||||
SetNavCursorVisibleAfterMove();
|
||||
}
|
||||
if (g.ActiveId == id)
|
||||
{
|
||||
@@ -4984,7 +5011,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (Shortcut(ImGuiKey_Tab, ImGuiInputFlags_Repeat, id))
|
||||
{
|
||||
unsigned int c = '\t'; // Insert TAB
|
||||
if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data))
|
||||
if (InputTextFilterCharacter(&g, state, &c, callback, callback_user_data))
|
||||
state->OnCharPressed(c);
|
||||
}
|
||||
// FIXME: Implement Shift+Tab
|
||||
@@ -5007,7 +5034,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
unsigned int c = (unsigned int)io.InputQueueCharacters[n];
|
||||
if (c == '\t') // Skip Tab, see above.
|
||||
continue;
|
||||
if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data))
|
||||
if (InputTextFilterCharacter(&g, state, &c, callback, callback_user_data))
|
||||
state->OnCharPressed(c);
|
||||
}
|
||||
|
||||
@@ -5093,7 +5120,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
// Insert new line
|
||||
unsigned int c = '\n';
|
||||
if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data))
|
||||
if (InputTextFilterCharacter(&g, state, &c, callback, callback_user_data))
|
||||
state->OnCharPressed(c);
|
||||
}
|
||||
}
|
||||
@@ -5162,7 +5189,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
unsigned int c;
|
||||
int in_len = ImTextCharFromUtf8(&c, s, clipboard_end);
|
||||
s += in_len;
|
||||
if (!InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, true))
|
||||
if (!InputTextFilterCharacter(&g, state, &c, callback, callback_user_data, true))
|
||||
continue;
|
||||
char c_utf8[5];
|
||||
ImTextCharToUtf8(c_utf8, c);
|
||||
@@ -5261,8 +5288,10 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
ImGuiInputTextCallbackData callback_data;
|
||||
callback_data.Ctx = &g;
|
||||
callback_data.EventFlag = event_flag;
|
||||
callback_data.ID = id;
|
||||
callback_data.Flags = flags;
|
||||
callback_data.EventFlag = event_flag;
|
||||
callback_data.EventActivated = (g.ActiveId == state->ID && g.ActiveIdIsJustActivated);
|
||||
callback_data.UserData = callback_user_data;
|
||||
|
||||
// FIXME-OPT: Undo stack reconcile needs a backup of the data until we rework API, see #7925
|
||||
@@ -5338,8 +5367,10 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
ImGuiInputTextCallbackData callback_data;
|
||||
callback_data.Ctx = &g;
|
||||
callback_data.EventFlag = ImGuiInputTextFlags_CallbackResize;
|
||||
callback_data.ID = id;
|
||||
callback_data.Flags = flags;
|
||||
callback_data.EventFlag = ImGuiInputTextFlags_CallbackResize;
|
||||
callback_data.EventActivated = (g.ActiveId == state->ID && g.ActiveIdIsJustActivated);
|
||||
callback_data.Buf = buf;
|
||||
callback_data.BufTextLen = apply_new_text_length;
|
||||
callback_data.BufSize = ImMax(buf_size, apply_new_text_length + 1);
|
||||
@@ -5369,7 +5400,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
}
|
||||
|
||||
ImVec2 draw_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding;
|
||||
ImVec2 text_size(0.0f, 0.0f);
|
||||
ImRect clip_rect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + inner_size.x, frame_bb.Min.y + inner_size.y); // Not using frame_bb.Max because we have adjusted size
|
||||
if (is_multiline)
|
||||
clip_rect.ClipWith(draw_window->ClipRect);
|
||||
@@ -5427,7 +5457,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
line_visible_n1 = ImMin(line_visible_n1, line_count);
|
||||
|
||||
// Store text height (we don't need width)
|
||||
text_size = ImVec2(inner_size.x, line_count * g.FontSize);
|
||||
float text_size_y = line_count * g.FontSize;
|
||||
//GetForegroundDrawList()->AddRect(draw_pos + ImVec2(0, line_visible_n0 * g.FontSize), draw_pos + ImVec2(frame_size.x, line_visible_n1 * g.FontSize), IM_COL32(255, 0, 0, 255));
|
||||
|
||||
// Calculate blinking cursor position
|
||||
@@ -5487,7 +5517,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
}
|
||||
if (new_scroll_y != scroll_y)
|
||||
{
|
||||
const float scroll_max_y = ImMax((text_size.y + style.FramePadding.y * 2.0f) - inner_size.y, 0.0f);
|
||||
const float scroll_max_y = ImMax((text_size_y + style.FramePadding.y * 2.0f) - inner_size.y, 0.0f);
|
||||
scroll_y = ImClamp(new_scroll_y, 0.0f, scroll_max_y);
|
||||
draw_pos.y += (draw_window->Scroll.y - scroll_y); // Manipulate cursor pos immediately avoid a frame of lag
|
||||
draw_window->Scroll.y = scroll_y;
|
||||
@@ -5580,7 +5610,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (is_multiline)
|
||||
{
|
||||
// For focus requests to work on our multiline we need to ensure our child ItemAdd() call specifies the ImGuiItemFlags_Inputable (see #4761, #7870)...
|
||||
Dummy(ImVec2(text_size.x, text_size.y + style.FramePadding.y));
|
||||
Dummy(ImVec2(0.0f, text_size_y + style.FramePadding.y));
|
||||
g.NextItemData.ItemFlags |= (ImGuiItemFlags)ImGuiItemFlags_Inputable | ImGuiItemFlags_NoTabStop;
|
||||
EndChild();
|
||||
item_data_backup.StatusFlags |= (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredWindow);
|
||||
@@ -5595,7 +5625,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
g.LastItemData.StatusFlags = item_data_backup.StatusFlags;
|
||||
}
|
||||
}
|
||||
if (state)
|
||||
if (state && is_readonly)
|
||||
state->TextSrc = NULL;
|
||||
|
||||
// Log as text
|
||||
@@ -5779,8 +5809,10 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
{
|
||||
// RGB/HSV 0..255 Sliders
|
||||
const float w_items = w_inputs - style.ItemInnerSpacing.x * (components - 1);
|
||||
const float w_per_component = IM_TRUNC(w_items / components);
|
||||
const bool draw_color_marker = (flags & (ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_NoColorMarkers)) == 0;
|
||||
|
||||
const bool hide_prefix = (IM_TRUNC(w_items / components) <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x);
|
||||
const bool hide_prefix = draw_color_marker || (w_per_component <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x);
|
||||
static const char* ids[4] = { "##X", "##Y", "##Z", "##W" };
|
||||
static const char* fmt_table_int[3][4] =
|
||||
{
|
||||
@@ -5795,6 +5827,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
{ "H:%0.3f", "S:%0.3f", "V:%0.3f", "A:%0.3f" } // Long display for HSVA
|
||||
};
|
||||
const int fmt_idx = hide_prefix ? 0 : (flags & ImGuiColorEditFlags_DisplayHSV) ? 2 : 1;
|
||||
const ImGuiSliderFlags drag_flags = draw_color_marker ? ImGuiSliderFlags_ColorMarkers : ImGuiSliderFlags_None;
|
||||
|
||||
float prev_split = 0.0f;
|
||||
for (int n = 0; n < components; n++)
|
||||
@@ -5804,16 +5837,18 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
float next_split = IM_TRUNC(w_items * (n + 1) / components);
|
||||
SetNextItemWidth(ImMax(next_split - prev_split, 1.0f));
|
||||
prev_split = next_split;
|
||||
if (draw_color_marker)
|
||||
SetNextItemColorMarker(GDefaultRgbaColorMarkers[n]);
|
||||
|
||||
// FIXME: When ImGuiColorEditFlags_HDR flag is passed HS values snap in weird ways when SV values go below 0.
|
||||
if (flags & ImGuiColorEditFlags_Float)
|
||||
{
|
||||
value_changed |= DragFloat(ids[n], &f[n], 1.0f / 255.0f, 0.0f, hdr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n]);
|
||||
value_changed |= DragFloat(ids[n], &f[n], 1.0f / 255.0f, 0.0f, hdr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n], drag_flags);
|
||||
value_changed_as_float |= value_changed;
|
||||
}
|
||||
else
|
||||
{
|
||||
value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]);
|
||||
value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n], drag_flags);
|
||||
}
|
||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||
OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight);
|
||||
@@ -5824,11 +5859,11 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
// RGB Hexadecimal Input
|
||||
char buf[64];
|
||||
if (alpha)
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255), ImClamp(i[3], 0, 255));
|
||||
ImFormatString(buf, IM_COUNTOF(buf), "#%02X%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255), ImClamp(i[3], 0, 255));
|
||||
else
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255));
|
||||
ImFormatString(buf, IM_COUNTOF(buf), "#%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255));
|
||||
SetNextItemWidth(w_inputs);
|
||||
if (InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsUppercase))
|
||||
if (InputText("##Text", buf, IM_COUNTOF(buf), ImGuiInputTextFlags_CharsUppercase))
|
||||
{
|
||||
value_changed = true;
|
||||
char* p = buf;
|
||||
@@ -6436,6 +6471,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
||||
}
|
||||
|
||||
// Initialize/override default color options
|
||||
// FIXME: Could be moved to a simple IO field.
|
||||
void ImGui::SetColorEditOptions(ImGuiColorEditFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@@ -6522,18 +6558,18 @@ void ImGui::ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags)
|
||||
{
|
||||
int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]);
|
||||
char buf[64];
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "(%.3ff, %.3ff, %.3ff, %.3ff)", col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]);
|
||||
ImFormatString(buf, IM_COUNTOF(buf), "(%.3ff, %.3ff, %.3ff, %.3ff)", col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]);
|
||||
if (Selectable(buf))
|
||||
SetClipboardText(buf);
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "(%d,%d,%d,%d)", cr, cg, cb, ca);
|
||||
ImFormatString(buf, IM_COUNTOF(buf), "(%d,%d,%d,%d)", cr, cg, cb, ca);
|
||||
if (Selectable(buf))
|
||||
SetClipboardText(buf);
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", cr, cg, cb);
|
||||
ImFormatString(buf, IM_COUNTOF(buf), "#%02X%02X%02X", cr, cg, cb);
|
||||
if (Selectable(buf))
|
||||
SetClipboardText(buf);
|
||||
if (!(flags & ImGuiColorEditFlags_NoAlpha))
|
||||
{
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", cr, cg, cb, ca);
|
||||
ImFormatString(buf, IM_COUNTOF(buf), "#%02X%02X%02X%02X", cr, cg, cb, ca);
|
||||
if (Selectable(buf))
|
||||
SetClipboardText(buf);
|
||||
}
|
||||
@@ -6774,7 +6810,6 @@ static void TreeNodeStoreStackData(ImGuiTreeNodeFlags flags, float x1)
|
||||
window->DC.TreeRecordsClippedNodesY2Mask |= (1 << window->DC.TreeDepth);
|
||||
}
|
||||
|
||||
// When using public API, currently 'id == storage_id' is always true, but we separate the values to facilitate advanced user code doing storage queries outside of UI loop.
|
||||
bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
@@ -6783,26 +6818,28 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
|
||||
// When not framed, we vertically increase height up to typical framed widget height
|
||||
const bool display_frame = (flags & ImGuiTreeNodeFlags_Framed) != 0;
|
||||
const ImVec2 padding = (display_frame || (flags & ImGuiTreeNodeFlags_FramePadding)) ? style.FramePadding : ImVec2(style.FramePadding.x, ImMin(window->DC.CurrLineTextBaseOffset, style.FramePadding.y));
|
||||
const bool use_frame_padding = (display_frame || (flags & ImGuiTreeNodeFlags_FramePadding));
|
||||
const ImVec2 padding = use_frame_padding ? style.FramePadding : ImVec2(style.FramePadding.x, ImMin(window->DC.CurrLineTextBaseOffset, style.FramePadding.y));
|
||||
|
||||
if (!label_end)
|
||||
label_end = FindRenderedTextEnd(label);
|
||||
const ImVec2 label_size = CalcTextSize(label, label_end, false);
|
||||
|
||||
const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapsing arrow width + Spacing
|
||||
const float text_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it
|
||||
const float text_offset_y = use_frame_padding ? ImMax(style.FramePadding.y, window->DC.CurrLineTextBaseOffset) : window->DC.CurrLineTextBaseOffset; // Latch before ItemSize changes it
|
||||
const float text_width = g.FontSize + label_size.x + padding.x * 2; // Include collapsing arrow
|
||||
|
||||
// We vertically grow up to current line height up the typical widget height.
|
||||
const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2);
|
||||
const float frame_height = label_size.y + padding.y * 2;
|
||||
const bool span_all_columns = (flags & ImGuiTreeNodeFlags_SpanAllColumns) != 0 && (g.CurrentTable != NULL);
|
||||
const bool span_all_columns_label = (flags & ImGuiTreeNodeFlags_LabelSpanAllColumns) != 0 && (g.CurrentTable != NULL);
|
||||
ImRect frame_bb;
|
||||
frame_bb.Min.x = span_all_columns ? window->ParentWorkRect.Min.x : (flags & ImGuiTreeNodeFlags_SpanFullWidth) ? window->WorkRect.Min.x : window->DC.CursorPos.x;
|
||||
frame_bb.Min.y = window->DC.CursorPos.y;
|
||||
frame_bb.Min.y = window->DC.CursorPos.y + (text_offset_y - padding.y);
|
||||
frame_bb.Max.x = span_all_columns ? window->ParentWorkRect.Max.x : (flags & ImGuiTreeNodeFlags_SpanLabelWidth) ? window->DC.CursorPos.x + text_width + padding.x : window->WorkRect.Max.x;
|
||||
frame_bb.Max.y = window->DC.CursorPos.y + frame_height;
|
||||
frame_bb.Max.y = window->DC.CursorPos.y + (text_offset_y - padding.y) + frame_height;
|
||||
if (display_frame)
|
||||
{
|
||||
const float outer_extend = IM_TRUNC(window->WindowPadding.x * 0.5f); // Framed header expand a little outside of current limits
|
||||
@@ -7485,7 +7522,7 @@ ImGuiTypingSelectRequest* ImGui::GetTypingSelectRequest(ImGuiTypingSelectFlags f
|
||||
}
|
||||
|
||||
// Append to buffer
|
||||
const int buffer_max_len = IM_ARRAYSIZE(data->SearchBuffer) - 1;
|
||||
const int buffer_max_len = IM_COUNTOF(data->SearchBuffer) - 1;
|
||||
int buffer_len = (int)ImStrlen(data->SearchBuffer);
|
||||
bool select_request = false;
|
||||
for (ImWchar w : g.IO.InputQueueCharacters)
|
||||
@@ -8885,7 +8922,7 @@ void ImGui::Value(const char* prefix, float v, const char* float_format)
|
||||
if (float_format)
|
||||
{
|
||||
char fmt[64];
|
||||
ImFormatString(fmt, IM_ARRAYSIZE(fmt), "%%s: %s", float_format);
|
||||
ImFormatString(fmt, IM_COUNTOF(fmt), "%%s: %s", float_format);
|
||||
Text(fmt, prefix, v);
|
||||
}
|
||||
else
|
||||
@@ -8924,7 +8961,7 @@ void ImGuiMenuColumns::CalcNextTotalWidth(bool update_offsets)
|
||||
{
|
||||
ImU16 offset = 0;
|
||||
bool want_spacing = false;
|
||||
for (int i = 0; i < IM_ARRAYSIZE(Widths); i++)
|
||||
for (int i = 0; i < IM_COUNTOF(Widths); i++)
|
||||
{
|
||||
ImU16 width = Widths[i];
|
||||
if (want_spacing && width > 0)
|
||||
@@ -9021,6 +9058,10 @@ void ImGui::EndMenuBar()
|
||||
NavMoveRequestForward(g.NavMoveDir, g.NavMoveClipDir, g.NavMoveFlags, g.NavMoveScrollFlags); // Repeat
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NavMoveRequestTryWrapping(window, ImGuiNavMoveFlags_WrapX);
|
||||
}
|
||||
|
||||
PopClipRect();
|
||||
PopID();
|
||||
@@ -9106,11 +9147,7 @@ bool ImGui::BeginMainMenuBar()
|
||||
void ImGui::EndMainMenuBar()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (!g.CurrentWindow->DC.MenuBarAppending)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(0, "Calling EndMainMenuBar() not from a menu-bar!"); // Not technically testing that it is the main menu bar
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(g.CurrentWindow->DC.MenuBarAppending, "Calling EndMainMenuBar() not from a menu-bar!"); // Not technically testing that it is the main menu bar
|
||||
|
||||
EndMenuBar();
|
||||
g.CurrentWindow->Flags |= ImGuiWindowFlags_NoSavedSettings; // Restore _NoSavedSettings (#8356)
|
||||
@@ -9190,7 +9227,8 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
// The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu,
|
||||
// However the final position is going to be different! It is chosen by FindBestWindowPosForPopup().
|
||||
// e.g. Menus tend to overlap each other horizontally to amplify relative Z-ordering.
|
||||
ImVec2 popup_pos, pos = window->DC.CursorPos;
|
||||
ImVec2 popup_pos;
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
PushID(label);
|
||||
if (!enabled)
|
||||
BeginDisabled();
|
||||
@@ -9204,34 +9242,34 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
// Menu inside a horizontal menu bar
|
||||
// Selectable extend their highlight by half ItemSpacing in each direction.
|
||||
// For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin()
|
||||
popup_pos = ImVec2(pos.x - 1.0f - IM_TRUNC(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight);
|
||||
window->DC.CursorPos.x += IM_TRUNC(style.ItemSpacing.x * 0.5f);
|
||||
PushStyleVarX(ImGuiStyleVar_ItemSpacing, style.ItemSpacing.x * 2.0f);
|
||||
float w = label_size.x;
|
||||
ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
||||
ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, pos.y + window->DC.CurrLineTextBaseOffset);
|
||||
pressed = Selectable("", menu_is_open, selectable_flags, ImVec2(w, label_size.y));
|
||||
LogSetNextTextDecoration("[", "]");
|
||||
RenderText(text_pos, label);
|
||||
PopStyleVar();
|
||||
window->DC.CursorPos.x += IM_TRUNC(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
|
||||
popup_pos = ImVec2(pos.x - 1.0f - IM_TRUNC(style.ItemSpacing.x * 0.5f), text_pos.y - style.FramePadding.y + window->MenuBarHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Menu inside a regular/vertical menu
|
||||
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
|
||||
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.)
|
||||
popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y);
|
||||
float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f;
|
||||
float checkmark_w = IM_TRUNC(g.FontSize * 1.20f);
|
||||
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, 0.0f, checkmark_w); // Feedback to next frame
|
||||
float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
|
||||
ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
||||
ImVec2 text_pos(window->DC.CursorPos.x, pos.y + window->DC.CurrLineTextBaseOffset);
|
||||
pressed = Selectable("", menu_is_open, selectable_flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, label_size.y));
|
||||
LogSetNextTextDecoration("", ">");
|
||||
RenderText(text_pos, label);
|
||||
RenderText(ImVec2(text_pos.x + offsets->OffsetLabel, text_pos.y), label);
|
||||
if (icon_w > 0.0f)
|
||||
RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon);
|
||||
RenderArrow(window->DrawList, pos + ImVec2(offsets->OffsetMark + extra_w + g.FontSize * 0.30f, 0.0f), GetColorU32(ImGuiCol_Text), ImGuiDir_Right);
|
||||
RenderText(ImVec2(text_pos.x + offsets->OffsetIcon, text_pos.y), icon);
|
||||
RenderArrow(window->DrawList, ImVec2(text_pos.x + offsets->OffsetMark + extra_w + g.FontSize * 0.30f, text_pos.y), GetColorU32(ImGuiCol_Text), ImGuiDir_Right);
|
||||
popup_pos = ImVec2(pos.x, text_pos.y - style.WindowPadding.y);
|
||||
}
|
||||
if (!enabled)
|
||||
EndDisabled();
|
||||
@@ -9369,7 +9407,8 @@ void ImGui::EndMenu()
|
||||
// Nav: When a left move request our menu failed, close ourselves.
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginMenu()/EndMenu() calls
|
||||
IM_ASSERT_USER_ERROR_RET((window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu), "Calling EndMenu() in wrong window!");
|
||||
|
||||
ImGuiWindow* parent_window = window->ParentWindow; // Should always be != NULL is we passed assert.
|
||||
if (window->BeginCount == window->BeginCountPreviousFrame)
|
||||
if (g.NavMoveDir == ImGuiDir_Left && NavMoveRequestButNoResultYet())
|
||||
@@ -9432,21 +9471,22 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
|
||||
float checkmark_w = IM_TRUNC(g.FontSize * 1.20f);
|
||||
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, shortcut_w, checkmark_w); // Feedback for next frame
|
||||
float stretch_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
|
||||
ImVec2 text_pos(pos.x, pos.y + window->DC.CurrLineTextBaseOffset);
|
||||
pressed = Selectable("", false, selectable_flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, label_size.y));
|
||||
if (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible)
|
||||
{
|
||||
RenderText(pos + ImVec2(offsets->OffsetLabel, 0.0f), label);
|
||||
RenderText(text_pos + ImVec2(offsets->OffsetLabel, 0.0f), label);
|
||||
if (icon_w > 0.0f)
|
||||
RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon);
|
||||
RenderText(text_pos + ImVec2(offsets->OffsetIcon, 0.0f), icon);
|
||||
if (shortcut_w > 0.0f)
|
||||
{
|
||||
PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]);
|
||||
LogSetNextTextDecoration("(", ")");
|
||||
RenderText(pos + ImVec2(offsets->OffsetShortcut + stretch_w, 0.0f), shortcut, NULL, false);
|
||||
RenderText(text_pos + ImVec2(offsets->OffsetShortcut + stretch_w, 0.0f), shortcut, NULL, false);
|
||||
PopStyleColor();
|
||||
}
|
||||
if (selected)
|
||||
RenderCheckMark(window->DrawList, pos + ImVec2(offsets->OffsetMark + stretch_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(ImGuiCol_Text), g.FontSize * 0.866f);
|
||||
RenderCheckMark(window->DrawList, text_pos + ImVec2(offsets->OffsetMark + stretch_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(ImGuiCol_Text), g.FontSize * 0.866f);
|
||||
}
|
||||
}
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0));
|
||||
@@ -9507,7 +9547,7 @@ struct ImGuiTabBarSection
|
||||
float WidthAfterShrinkMinWidth;
|
||||
float Spacing; // Horizontal spacing at the end of the section.
|
||||
|
||||
ImGuiTabBarSection() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiTabBarSection() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
namespace ImGui
|
||||
@@ -9523,7 +9563,7 @@ namespace ImGui
|
||||
|
||||
ImGuiTabBar::ImGuiTabBar()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
CurrFrameVisible = PrevFrameVisible = -1;
|
||||
LastTabItemIdx = -1;
|
||||
}
|
||||
@@ -9665,11 +9705,7 @@ void ImGui::EndTabBar()
|
||||
return;
|
||||
|
||||
ImGuiTabBar* tab_bar = g.CurrentTabBar;
|
||||
if (tab_bar == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(tab_bar != NULL, "Mismatched BeginTabBar()/EndTabBar()!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(tab_bar != NULL, "Mismatched BeginTabBar()/EndTabBar()!");
|
||||
|
||||
// Fallback in case no TabItem have been submitted
|
||||
if (tab_bar->WantLayout)
|
||||
@@ -9758,11 +9794,17 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
ImQsort(tab_bar->Tabs.Data, tab_bar->Tabs.Size, sizeof(ImGuiTabItem), TabItemComparerBySection);
|
||||
|
||||
// Calculate spacing between sections
|
||||
sections[0].Spacing = sections[0].TabCount > 0 && (sections[1].TabCount + sections[2].TabCount) > 0 ? g.Style.ItemInnerSpacing.x : 0.0f;
|
||||
sections[1].Spacing = sections[1].TabCount > 0 && sections[2].TabCount > 0 ? g.Style.ItemInnerSpacing.x : 0.0f;
|
||||
const float tab_spacing = g.Style.ItemInnerSpacing.x;
|
||||
sections[0].Spacing = sections[0].TabCount > 0 && (sections[1].TabCount + sections[2].TabCount) > 0 ? tab_spacing : 0.0f;
|
||||
sections[1].Spacing = sections[1].TabCount > 0 && sections[2].TabCount > 0 ? tab_spacing : 0.0f;
|
||||
|
||||
// Setup next selected tab
|
||||
ImGuiID scroll_to_tab_id = 0;
|
||||
if (tab_bar->NextScrollToTabId)
|
||||
{
|
||||
scroll_to_tab_id = tab_bar->NextScrollToTabId;
|
||||
tab_bar->NextScrollToTabId = 0;
|
||||
}
|
||||
if (tab_bar->NextSelectedTabId)
|
||||
{
|
||||
tab_bar->SelectedTabId = tab_bar->NextSelectedTabId;
|
||||
@@ -9820,8 +9862,8 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
|
||||
int section_n = TabItemGetSectionIdx(tab);
|
||||
ImGuiTabBarSection* section = §ions[section_n];
|
||||
section->Width += tab->ContentWidth + (section_n == curr_section_n ? g.Style.ItemInnerSpacing.x : 0.0f);
|
||||
section->WidthAfterShrinkMinWidth += ImMin(tab->ContentWidth, shrink_min_width) + (section_n == curr_section_n ? g.Style.ItemInnerSpacing.x : 0.0f);
|
||||
section->Width += tab->ContentWidth + (section_n == curr_section_n ? tab_spacing : 0.0f);
|
||||
section->WidthAfterShrinkMinWidth += ImMin(tab->ContentWidth, shrink_min_width) + (section_n == curr_section_n ? tab_spacing : 0.0f);
|
||||
curr_section_n = section_n;
|
||||
|
||||
// Store data so we can build an array sorted by width if we need to shrink tabs down
|
||||
@@ -10126,6 +10168,7 @@ void ImGui::TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, ImGuiTabItem* s
|
||||
if ((tab_bar->Flags & ImGuiTabBarFlags_Reorderable) == 0)
|
||||
return;
|
||||
|
||||
const float tab_spacing = g.Style.ItemInnerSpacing.x;
|
||||
const bool is_central_section = (src_tab->Flags & ImGuiTabItemFlags_SectionMask_) == 0;
|
||||
const float bar_offset = tab_bar->BarRect.Min.x - (is_central_section ? tab_bar->ScrollingTarget : 0);
|
||||
|
||||
@@ -10144,8 +10187,8 @@ void ImGui::TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, ImGuiTabItem* s
|
||||
dst_idx = i;
|
||||
|
||||
// Include spacing after tab, so when mouse cursor is between tabs we would not continue checking further tabs that are not hovered.
|
||||
const float x1 = bar_offset + dst_tab->Offset - g.Style.ItemInnerSpacing.x;
|
||||
const float x2 = bar_offset + dst_tab->Offset + dst_tab->Width + g.Style.ItemInnerSpacing.x;
|
||||
const float x1 = bar_offset + dst_tab->Offset - tab_spacing;
|
||||
const float x2 = bar_offset + dst_tab->Offset + dst_tab->Width + tab_spacing;
|
||||
//GetForegroundDrawList()->AddRect(ImVec2(x1, tab_bar->BarRect.Min.y), ImVec2(x2, tab_bar->BarRect.Max.y), IM_COL32(255, 0, 0, 255));
|
||||
if ((dir < 0 && mouse_pos.x > x1) || (dir > 0 && mouse_pos.x < x2))
|
||||
break;
|
||||
@@ -10308,11 +10351,7 @@ bool ImGui::BeginTabItem(const char* label, bool* p_open, ImGuiTabItemFlags f
|
||||
return false;
|
||||
|
||||
ImGuiTabBar* tab_bar = g.CurrentTabBar;
|
||||
if (tab_bar == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(tab_bar, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
return false;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RETV(tab_bar != NULL, false, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
IM_ASSERT((flags & ImGuiTabItemFlags_Button) == 0); // BeginTabItem() Can't be used with button flags, use TabItemButton() instead!
|
||||
|
||||
bool ret = TabItemEx(tab_bar, label, p_open, flags, NULL);
|
||||
@@ -10332,11 +10371,7 @@ void ImGui::EndTabItem()
|
||||
return;
|
||||
|
||||
ImGuiTabBar* tab_bar = g.CurrentTabBar;
|
||||
if (tab_bar == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
IM_ASSERT(tab_bar->LastTabItemIdx >= 0);
|
||||
ImGuiTabItem* tab = &tab_bar->Tabs[tab_bar->LastTabItemIdx];
|
||||
if (!(tab->Flags & ImGuiTabItemFlags_NoPushId))
|
||||
@@ -10351,11 +10386,7 @@ bool ImGui::TabItemButton(const char* label, ImGuiTabItemFlags flags)
|
||||
return false;
|
||||
|
||||
ImGuiTabBar* tab_bar = g.CurrentTabBar;
|
||||
if (tab_bar == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
return false;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RETV(tab_bar != NULL, false, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
return TabItemEx(tab_bar, label, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder, NULL);
|
||||
}
|
||||
|
||||
@@ -10367,11 +10398,7 @@ void ImGui::TabItemSpacing(const char* str_id, ImGuiTabItemFlags flags, float
|
||||
return;
|
||||
|
||||
ImGuiTabBar* tab_bar = g.CurrentTabBar;
|
||||
if (tab_bar == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
SetNextItemWidth(width);
|
||||
TabItemEx(tab_bar, str_id, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder | ImGuiTabItemFlags_Invisible, NULL);
|
||||
}
|
||||
|
||||
Vendored
+17
-1
@@ -1,7 +1,8 @@
|
||||
// Generated by https://github.com/juliettef/IconFontCppHeaders script GenerateIconFontCppHeaders.py
|
||||
// for C and C++
|
||||
// from codepoints https://github.com/FortAwesome/Font-Awesome/raw/7.x/metadata/icons.yml
|
||||
// for use with font https://github.com/FortAwesome/Font-Awesome/blob/7.x/webfonts/fa-regular-400.woff2 (You may need to convert the .woff2 files to .ttf depending upon your loader.), https://github.com/FortAwesome/Font-Awesome/blob/7.x/webfonts/fa-solid-900.woff2 (You may need to convert the .woff2 files to .ttf depending upon your loader.)
|
||||
// for use with font https://github.com/FortAwesome/Font-Awesome/blob/7.x/otfs/Font Awesome 7 Free-Regular-400.otf, https://github.com/FortAwesome/Font-Awesome/blob/7.x/otfs/Font Awesome 7 Free-Solid-900.otf
|
||||
// converted to ttf
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -45,7 +46,9 @@
|
||||
#define ICON_FA_ANGLES_UP "\xef\x84\x82" // U+f102
|
||||
#define ICON_FA_ANKH "\xef\x99\x84" // U+f644
|
||||
#define ICON_FA_APPLE_WHOLE "\xef\x97\x91" // U+f5d1
|
||||
#define ICON_FA_AQUARIUS "\xee\xa1\x85" // U+e845
|
||||
#define ICON_FA_ARCHWAY "\xef\x95\x97" // U+f557
|
||||
#define ICON_FA_ARIES "\xee\xa1\x86" // U+e846
|
||||
#define ICON_FA_ARROW_DOWN "\xef\x81\xa3" // U+f063
|
||||
#define ICON_FA_ARROW_DOWN_1_9 "\xef\x85\xa2" // U+f162
|
||||
#define ICON_FA_ARROW_DOWN_9_1 "\xef\xa2\x86" // U+f886
|
||||
@@ -238,8 +241,10 @@
|
||||
#define ICON_FA_CAMERA_RETRO "\xef\x82\x83" // U+f083
|
||||
#define ICON_FA_CAMERA_ROTATE "\xee\x83\x98" // U+e0d8
|
||||
#define ICON_FA_CAMPGROUND "\xef\x9a\xbb" // U+f6bb
|
||||
#define ICON_FA_CANCER "\xee\xa1\x87" // U+e847
|
||||
#define ICON_FA_CANDY_CANE "\xef\x9e\x86" // U+f786
|
||||
#define ICON_FA_CANNABIS "\xef\x95\x9f" // U+f55f
|
||||
#define ICON_FA_CAPRICORN "\xee\xa1\x88" // U+e848
|
||||
#define ICON_FA_CAPSULES "\xef\x91\xab" // U+f46b
|
||||
#define ICON_FA_CAR "\xef\x86\xb9" // U+f1b9
|
||||
#define ICON_FA_CAR_BATTERY "\xef\x97\x9f" // U+f5df
|
||||
@@ -341,6 +346,7 @@
|
||||
#define ICON_FA_CLOCK_ROTATE_LEFT "\xef\x87\x9a" // U+f1da
|
||||
#define ICON_FA_CLONE "\xef\x89\x8d" // U+f24d
|
||||
#define ICON_FA_CLOSED_CAPTIONING "\xef\x88\x8a" // U+f20a
|
||||
#define ICON_FA_CLOSED_CAPTIONING_SLASH "\xee\x84\xb5" // U+e135
|
||||
#define ICON_FA_CLOUD "\xef\x83\x82" // U+f0c2
|
||||
#define ICON_FA_CLOUD_ARROW_DOWN "\xef\x83\xad" // U+f0ed
|
||||
#define ICON_FA_CLOUD_ARROW_UP "\xef\x83\xae" // U+f0ee
|
||||
@@ -595,6 +601,7 @@
|
||||
#define ICON_FA_GEAR "\xef\x80\x93" // U+f013
|
||||
#define ICON_FA_GEARS "\xef\x82\x85" // U+f085
|
||||
#define ICON_FA_GEM "\xef\x8e\xa5" // U+f3a5
|
||||
#define ICON_FA_GEMINI "\xee\xa1\x89" // U+e849
|
||||
#define ICON_FA_GENDERLESS "\xef\x88\xad" // U+f22d
|
||||
#define ICON_FA_GHOST "\xef\x9b\xa2" // U+f6e2
|
||||
#define ICON_FA_GIFT "\xef\x81\xab" // U+f06b
|
||||
@@ -777,8 +784,10 @@
|
||||
#define ICON_FA_LEFT_LONG "\xef\x8c\x8a" // U+f30a
|
||||
#define ICON_FA_LEFT_RIGHT "\xef\x8c\xb7" // U+f337
|
||||
#define ICON_FA_LEMON "\xef\x82\x94" // U+f094
|
||||
#define ICON_FA_LEO "\xee\xa1\x8a" // U+e84a
|
||||
#define ICON_FA_LESS_THAN "<" // U+003c
|
||||
#define ICON_FA_LESS_THAN_EQUAL "\xef\x94\xb7" // U+f537
|
||||
#define ICON_FA_LIBRA "\xee\xa1\x8b" // U+e84b
|
||||
#define ICON_FA_LIFE_RING "\xef\x87\x8d" // U+f1cd
|
||||
#define ICON_FA_LIGHTBULB "\xef\x83\xab" // U+f0eb
|
||||
#define ICON_FA_LINES_LEANING "\xee\x94\x9e" // U+e51e
|
||||
@@ -982,8 +991,10 @@
|
||||
#define ICON_FA_PHONE_SLASH "\xef\x8f\x9d" // U+f3dd
|
||||
#define ICON_FA_PHONE_VOLUME "\xef\x8a\xa0" // U+f2a0
|
||||
#define ICON_FA_PHOTO_FILM "\xef\xa1\xbc" // U+f87c
|
||||
#define ICON_FA_PICTURE_IN_PICTURE "\xee\xa0\x8b" // U+e80b
|
||||
#define ICON_FA_PIGGY_BANK "\xef\x93\x93" // U+f4d3
|
||||
#define ICON_FA_PILLS "\xef\x92\x84" // U+f484
|
||||
#define ICON_FA_PISCES "\xee\xa1\x8c" // U+e84c
|
||||
#define ICON_FA_PIZZA_SLICE "\xef\xa0\x98" // U+f818
|
||||
#define ICON_FA_PLACE_OF_WORSHIP "\xef\x99\xbf" // U+f67f
|
||||
#define ICON_FA_PLANE "\xef\x81\xb2" // U+f072
|
||||
@@ -1074,6 +1085,7 @@
|
||||
#define ICON_FA_S "S" // U+0053
|
||||
#define ICON_FA_SACK_DOLLAR "\xef\xa0\x9d" // U+f81d
|
||||
#define ICON_FA_SACK_XMARK "\xee\x95\xaa" // U+e56a
|
||||
#define ICON_FA_SAGITTARIUS "\xee\xa1\x8d" // U+e84d
|
||||
#define ICON_FA_SAILBOAT "\xee\x91\x85" // U+e445
|
||||
#define ICON_FA_SATELLITE "\xef\x9e\xbf" // U+f7bf
|
||||
#define ICON_FA_SATELLITE_DISH "\xef\x9f\x80" // U+f7c0
|
||||
@@ -1087,6 +1099,7 @@
|
||||
#define ICON_FA_SCHOOL_FLAG "\xee\x95\xae" // U+e56e
|
||||
#define ICON_FA_SCHOOL_LOCK "\xee\x95\xaf" // U+e56f
|
||||
#define ICON_FA_SCISSORS "\xef\x83\x84" // U+f0c4
|
||||
#define ICON_FA_SCORPIO "\xee\xa1\x8e" // U+e84e
|
||||
#define ICON_FA_SCREWDRIVER "\xef\x95\x8a" // U+f54a
|
||||
#define ICON_FA_SCREWDRIVER_WRENCH "\xef\x9f\x99" // U+f7d9
|
||||
#define ICON_FA_SCROLL "\xef\x9c\x8e" // U+f70e
|
||||
@@ -1230,6 +1243,7 @@
|
||||
#define ICON_FA_TAPE "\xef\x93\x9b" // U+f4db
|
||||
#define ICON_FA_TARP "\xee\x95\xbb" // U+e57b
|
||||
#define ICON_FA_TARP_DROPLET "\xee\x95\xbc" // U+e57c
|
||||
#define ICON_FA_TAURUS "\xee\xa1\x8f" // U+e84f
|
||||
#define ICON_FA_TAXI "\xef\x86\xba" // U+f1ba
|
||||
#define ICON_FA_TEETH "\xef\x98\xae" // U+f62e
|
||||
#define ICON_FA_TEETH_OPEN "\xef\x98\xaf" // U+f62f
|
||||
@@ -1369,6 +1383,7 @@
|
||||
#define ICON_FA_VIDEO "\xef\x80\xbd" // U+f03d
|
||||
#define ICON_FA_VIDEO_SLASH "\xef\x93\xa2" // U+f4e2
|
||||
#define ICON_FA_VIHARA "\xef\x9a\xa7" // U+f6a7
|
||||
#define ICON_FA_VIRGO "\xee\xa1\x90" // U+e850
|
||||
#define ICON_FA_VIRUS "\xee\x81\xb4" // U+e074
|
||||
#define ICON_FA_VIRUS_COVID "\xee\x92\xa8" // U+e4a8
|
||||
#define ICON_FA_VIRUS_COVID_SLASH "\xee\x92\xa9" // U+e4a9
|
||||
@@ -1377,6 +1392,7 @@
|
||||
#define ICON_FA_VOICEMAIL "\xef\xa2\x97" // U+f897
|
||||
#define ICON_FA_VOLCANO "\xef\x9d\xb0" // U+f770
|
||||
#define ICON_FA_VOLLEYBALL "\xef\x91\x9f" // U+f45f
|
||||
#define ICON_FA_VOLUME "\xef\x9a\xa8" // U+f6a8
|
||||
#define ICON_FA_VOLUME_HIGH "\xef\x80\xa8" // U+f028
|
||||
#define ICON_FA_VOLUME_LOW "\xef\x80\xa7" // U+f027
|
||||
#define ICON_FA_VOLUME_OFF "\xef\x80\xa6" // U+f026
|
||||
|
||||
Vendored
+66
-59
@@ -50,7 +50,6 @@
|
||||
#include <libchdr/huffman.h>
|
||||
#include <zstd.h>
|
||||
|
||||
#include "LzmaEnc.h"
|
||||
#include "LzmaDec.h"
|
||||
#if defined(__PS3__) || defined(__PSL1GHT__)
|
||||
#define __MACTYPES__
|
||||
@@ -466,28 +465,6 @@ static void lzma_allocator_free(void* p )
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* lzma_allocator_free_unused
|
||||
* free unused buffers only
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
static void lzma_allocator_free_unused(lzma_allocator *codec)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_LZMA_ALLOCS; i++)
|
||||
{
|
||||
uint32_t *ptr = codec->allocptr[i];
|
||||
if (ptr && (*ptr & 1) == 0)
|
||||
{
|
||||
free(codec->allocptr[i]);
|
||||
codec->allocptr[i] = NULL;
|
||||
codec->allocptr2[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* lzma_fast_alloc - fast malloc for lzma, which
|
||||
* allocates and frees memory frequently
|
||||
@@ -583,6 +560,61 @@ static void lzma_fast_free(void *p, void *address)
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
* lzma_compute_aligned_dictionary_size
|
||||
* Based on LzmaEncProps_Normalize, LzmaEnc_SetProps, LzmaEnc_WriteProperties.
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
static uint32_t lzma_compute_aligned_dictionary_size(uint32_t hunkbytes)
|
||||
{
|
||||
const unsigned int level = 9;
|
||||
const uint32_t reduceSize = hunkbytes;
|
||||
|
||||
uint32_t dictSize, alignedDictSize;
|
||||
|
||||
/* LzmaEncProps_Normalize */
|
||||
dictSize = level <= 4 ?
|
||||
(uint32_t)1 << (level * 2 + 16) :
|
||||
level <= sizeof(size_t) / 2 + 4 ?
|
||||
(uint32_t)1 << (level + 20) :
|
||||
(uint32_t)1 << (sizeof(size_t) / 2 + 24);
|
||||
|
||||
if (dictSize > reduceSize)
|
||||
{
|
||||
const uint32_t kReduceMin = (uint32_t)1 << 12;
|
||||
const uint32_t max = MIN(kReduceMin, reduceSize);
|
||||
|
||||
dictSize = MAX(max, dictSize);
|
||||
}
|
||||
|
||||
/* LzmaEnc_SetProps */
|
||||
dictSize = MIN((uint32_t)15 << 28, dictSize); /* kLzmaMaxHistorySize */
|
||||
|
||||
/* LzmaEnc_WriteProperties */
|
||||
/* we write aligned dictionary value to properties for lzma decoder */
|
||||
if (dictSize >= ((uint32_t)1 << 21))
|
||||
{
|
||||
const uint32_t kDictMask = ((uint32_t)1 << 20) - 1;
|
||||
|
||||
alignedDictSize = (dictSize + kDictMask) & ~kDictMask;
|
||||
alignedDictSize = MIN(dictSize, alignedDictSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int i = 11 * 2;
|
||||
|
||||
do
|
||||
{
|
||||
alignedDictSize = (uint32_t)(2 + (i & 1)) << (i >> 1);
|
||||
i++;
|
||||
}
|
||||
while (alignedDictSize < dictSize);
|
||||
}
|
||||
|
||||
return alignedDictSize;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* lzma_codec_init - constructor
|
||||
*-------------------------------------------------
|
||||
@@ -590,47 +622,22 @@ static void lzma_fast_free(void *p, void *address)
|
||||
|
||||
static chd_error lzma_codec_init(void* codec, uint32_t hunkbytes)
|
||||
{
|
||||
CLzmaEncHandle enc;
|
||||
CLzmaEncProps encoder_props;
|
||||
Byte decoder_props[LZMA_PROPS_SIZE];
|
||||
SizeT props_size;
|
||||
lzma_allocator* alloc;
|
||||
lzma_codec_data* lzma_codec = (lzma_codec_data*) codec;
|
||||
lzma_allocator* alloc = &lzma_codec->allocator;
|
||||
const uint32_t alignedDictSize = lzma_compute_aligned_dictionary_size(hunkbytes);
|
||||
|
||||
unsigned int i;
|
||||
Byte decoder_props[LZMA_PROPS_SIZE];
|
||||
|
||||
decoder_props[0] = 93;
|
||||
for (i = 0; i < LZMA_PROPS_SIZE - 1; ++i)
|
||||
decoder_props[1 + i] = (alignedDictSize >> (8 * i)) & 0xFF;
|
||||
|
||||
lzma_allocator_init(alloc);
|
||||
|
||||
/* construct the decoder */
|
||||
LzmaDec_Construct(&lzma_codec->decoder);
|
||||
|
||||
/* FIXME: this code is written in a way that makes it impossible to safely upgrade the LZMA SDK
|
||||
* This code assumes that the current version of the encoder imposes the same requirements on the
|
||||
* decoder as the encoder used to produce the file. This is not necessarily true. The format
|
||||
* needs to be changed so the encoder properties are written to the file.
|
||||
|
||||
* configure the properties like the compressor did */
|
||||
LzmaEncProps_Init(&encoder_props);
|
||||
encoder_props.level = 9;
|
||||
encoder_props.reduceSize = hunkbytes;
|
||||
LzmaEncProps_Normalize(&encoder_props);
|
||||
|
||||
/* convert to decoder properties */
|
||||
alloc = &lzma_codec->allocator;
|
||||
lzma_allocator_init(alloc);
|
||||
enc = LzmaEnc_Create((ISzAlloc*)alloc);
|
||||
if (!enc)
|
||||
return CHDERR_DECOMPRESSION_ERROR;
|
||||
if (LzmaEnc_SetProps(enc, &encoder_props) != SZ_OK)
|
||||
{
|
||||
LzmaEnc_Destroy(enc, (ISzAlloc*)&alloc, (ISzAlloc*)&alloc);
|
||||
return CHDERR_DECOMPRESSION_ERROR;
|
||||
}
|
||||
props_size = sizeof(decoder_props);
|
||||
if (LzmaEnc_WriteProperties(enc, decoder_props, &props_size) != SZ_OK)
|
||||
{
|
||||
LzmaEnc_Destroy(enc, (ISzAlloc*)alloc, (ISzAlloc*)alloc);
|
||||
return CHDERR_DECOMPRESSION_ERROR;
|
||||
}
|
||||
LzmaEnc_Destroy(enc, (ISzAlloc*)alloc, (ISzAlloc*)alloc);
|
||||
lzma_allocator_free_unused(alloc);
|
||||
|
||||
/* do memory allocations */
|
||||
if (LzmaDec_Allocate(&lzma_codec->decoder, decoder_props, LZMA_PROPS_SIZE, (ISzAlloc*)alloc) != SZ_OK)
|
||||
return CHDERR_DECOMPRESSION_ERROR;
|
||||
|
||||
Vendored
+14
-1
@@ -1,7 +1,7 @@
|
||||
#ifndef RA_CONSOLES_H
|
||||
#define RA_CONSOLES_H
|
||||
|
||||
/* this list should match the list in rcheevos/include/rconsoles.h */
|
||||
/* this list should match the list in rcheevos/include/rc_consoles.h */
|
||||
enum ConsoleID
|
||||
{
|
||||
UnknownConsoleID = 0,
|
||||
@@ -77,6 +77,19 @@ enum ConsoleID
|
||||
Zeebo = 70,
|
||||
Arduboy = 71,
|
||||
WASM4 = 72,
|
||||
Arcadia2001 = 73,
|
||||
IntertonVC4000 = 74,
|
||||
ElektorTVGamesComputer = 75,
|
||||
PCEngineCD = 76,
|
||||
JaguarCD = 77,
|
||||
DSi = 78,
|
||||
TI83 = 79,
|
||||
Uzebox = 80,
|
||||
FamicomDiskSystem = 81,
|
||||
|
||||
Hubs = 100,
|
||||
Events = 101,
|
||||
Standalone = 102,
|
||||
|
||||
NumConsoleIDs
|
||||
};
|
||||
|
||||
+213
-61
@@ -5,10 +5,23 @@
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#ifndef RA_NOPROGRESS
|
||||
#include <ShlObj.h>
|
||||
#else
|
||||
#define IProgressDialog void
|
||||
#endif
|
||||
|
||||
#ifndef CCONV
|
||||
#define CCONV __cdecl
|
||||
#endif
|
||||
|
||||
#if defined(_M_X64) || defined(__amd64__)
|
||||
#define RA_X64
|
||||
#define RA_INT_DLL L"RA_Integration-x64.dll"
|
||||
#else
|
||||
#define RA_INT_DLL L"RA_Integration.dll"
|
||||
#endif
|
||||
|
||||
// Initialization
|
||||
static const char* (CCONV* _RA_IntegrationVersion)() = nullptr;
|
||||
static const char* (CCONV* _RA_HostName)() = nullptr;
|
||||
@@ -270,10 +283,58 @@ void RA_DisableHardcore()
|
||||
_RA_WarnDisableHardcore(nullptr);
|
||||
}
|
||||
|
||||
static size_t DownloadToFile(char* pData, size_t nDataSize, void* pUserData)
|
||||
#ifndef RA_NOPROGRESS
|
||||
|
||||
static void FormatByteSize(DWORD nSize, wchar_t* sBuffer, size_t nBufferSize)
|
||||
{
|
||||
if (nSize < 1024)
|
||||
{
|
||||
swprintf_s(sBuffer, nBufferSize, L"%u bytes", nSize);
|
||||
return;
|
||||
}
|
||||
|
||||
float fSize = nSize;
|
||||
fSize /= 1024.0;
|
||||
if (fSize < 1024.0)
|
||||
{
|
||||
swprintf_s(sBuffer, nBufferSize, L"%.2f KB", fSize);
|
||||
return;
|
||||
}
|
||||
|
||||
fSize /= 1024.0;
|
||||
swprintf_s(sBuffer, nBufferSize, L"%.2f MB", fSize);
|
||||
}
|
||||
|
||||
static void SetProgressMessage(IProgressDialog* pProgressDialog, DWORD nProgress, DWORD nMax)
|
||||
{
|
||||
wchar_t sNum[32];
|
||||
std::wstring sMessage;
|
||||
|
||||
FormatByteSize(nProgress, sNum, sizeof(sNum) / sizeof(sNum[0]));
|
||||
sMessage.append(sNum);
|
||||
sMessage.append(L" of ");
|
||||
|
||||
FormatByteSize(nMax, sNum, sizeof(sNum) / sizeof(sNum[0]));
|
||||
sMessage.append(sNum);
|
||||
|
||||
pProgressDialog->SetLine(2, sMessage.c_str(), FALSE, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static size_t DownloadToFile(char* pData, size_t nDataSize, void* pUserData, DWORD* pStatusCode)
|
||||
{
|
||||
FILE* file = (FILE*)pUserData;
|
||||
return fwrite(pData, 1, nDataSize, file);
|
||||
size_t nBytesWritten = fwrite(pData, 1, nDataSize, file);
|
||||
if (nBytesWritten != nDataSize)
|
||||
{
|
||||
std::string sMessage;
|
||||
sMessage = "Error " + std::to_string(errno) + " writing file: " + strerror(errno);
|
||||
MessageBoxA(nullptr, sMessage.c_str(), "Error", MB_OK | MB_ICONERROR);
|
||||
*pStatusCode = 0;
|
||||
}
|
||||
|
||||
return nBytesWritten;
|
||||
}
|
||||
|
||||
typedef struct DownloadBuffer
|
||||
@@ -283,7 +344,7 @@ typedef struct DownloadBuffer
|
||||
size_t nOffset;
|
||||
} DownloadBuffer;
|
||||
|
||||
static size_t DownloadToBuffer(char* pData, size_t nDataSize, void* pUserData)
|
||||
static size_t DownloadToBuffer(char* pData, size_t nDataSize, void* pUserData, DWORD* pStatusCode)
|
||||
{
|
||||
DownloadBuffer* pBuffer = (DownloadBuffer*)pUserData;
|
||||
const size_t nRemaining = pBuffer->nBufferSize - pBuffer->nOffset;
|
||||
@@ -299,10 +360,10 @@ static size_t DownloadToBuffer(char* pData, size_t nDataSize, void* pUserData)
|
||||
return nDataSize;
|
||||
}
|
||||
|
||||
typedef size_t (DownloadFunc)(char* pData, size_t nDataSize, void* pUserData);
|
||||
typedef size_t (DownloadFunc)(char* pData, size_t nDataSize, void* pUserData, DWORD* pStatusCode);
|
||||
|
||||
static BOOL DoBlockingHttpCall(const char* sHostUrl, const char* sRequestedPage, const char* sPostData,
|
||||
DownloadFunc fnDownload, void* pDownloadUserData, DWORD* pBytesRead, DWORD* pStatusCode)
|
||||
DownloadFunc fnDownload, void* pDownloadUserData, DWORD* pBytesRead, DWORD* pStatusCode, IProgressDialog* pProgressDialog)
|
||||
{
|
||||
BOOL bResults = FALSE, bSuccess = FALSE;
|
||||
HINTERNET hSession = nullptr, hConnect = nullptr, hRequest = nullptr;
|
||||
@@ -355,6 +416,8 @@ static BOOL DoBlockingHttpCall(const char* sHostUrl, const char* sRequestedPage,
|
||||
mbstowcs_s(&nTemp, wBuffer, sizeof(wBuffer) / sizeof(wBuffer[0]), sHostName, nHostnameLen);
|
||||
#else
|
||||
nTemp = mbstowcs(wBuffer, sHostName, nHostnameLen);
|
||||
if (nTemp > 0)
|
||||
wBuffer[nTemp] = '\0';
|
||||
#endif
|
||||
|
||||
if (nTemp > 0)
|
||||
@@ -373,6 +436,8 @@ static BOOL DoBlockingHttpCall(const char* sHostUrl, const char* sRequestedPage,
|
||||
mbstowcs_s(&nTemp, wBuffer, sizeof(wBuffer) / sizeof(wBuffer[0]), sRequestedPage, strlen(sRequestedPage) + 1);
|
||||
#else
|
||||
nTemp = mbstowcs(wBuffer, sRequestedPage, strlen(sRequestedPage) + 1);
|
||||
if (nTemp > 0)
|
||||
wBuffer[nTemp] = '\0';
|
||||
#endif
|
||||
|
||||
hRequest = WinHttpOpenRequest(hConnect,
|
||||
@@ -410,12 +475,28 @@ static BOOL DoBlockingHttpCall(const char* sHostUrl, const char* sRequestedPage,
|
||||
}
|
||||
else
|
||||
{
|
||||
char buffer[16384];
|
||||
const DWORD nBufferSize = 16384;
|
||||
char* pBuffer = (char*)malloc(nBufferSize);
|
||||
DWORD dwSize = sizeof(DWORD);
|
||||
WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, pStatusCode, &dwSize, WINHTTP_NO_HEADER_INDEX);
|
||||
bSuccess = (*pStatusCode == 200);
|
||||
const DWORD nDefaultTotalBytes = 3 * 1024 * 1024;
|
||||
DWORD nTotalBytes = nDefaultTotalBytes;
|
||||
|
||||
bSuccess = TRUE;
|
||||
do
|
||||
#ifndef RA_NOPROGRESS
|
||||
if (pProgressDialog)
|
||||
{
|
||||
dwSize = nBufferSize;
|
||||
if (WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_LENGTH, WINHTTP_HEADER_NAME_BY_INDEX, pBuffer, &dwSize, WINHTTP_NO_HEADER_INDEX))
|
||||
{
|
||||
nTotalBytes = wcstoul((const wchar_t*)pBuffer, NULL, 10);
|
||||
|
||||
SetProgressMessage(pProgressDialog, 0, nTotalBytes);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while (bSuccess)
|
||||
{
|
||||
nBytesAvailable = 0;
|
||||
WinHttpQueryDataAvailable(hRequest, &nBytesAvailable);
|
||||
@@ -424,20 +505,17 @@ static BOOL DoBlockingHttpCall(const char* sHostUrl, const char* sRequestedPage,
|
||||
|
||||
do
|
||||
{
|
||||
if (nBytesAvailable > sizeof(buffer))
|
||||
nBytesToRead = sizeof(buffer);
|
||||
if (nBytesAvailable > nBufferSize)
|
||||
nBytesToRead = nBufferSize;
|
||||
else
|
||||
nBytesToRead = nBytesAvailable;
|
||||
|
||||
nBytesFetched = 0;
|
||||
if (WinHttpReadData(hRequest, buffer, nBytesToRead, &nBytesFetched))
|
||||
if (WinHttpReadData(hRequest, pBuffer, nBytesToRead, &nBytesFetched))
|
||||
{
|
||||
size_t nBytesWritten = fnDownload(buffer, nBytesFetched, pDownloadUserData);
|
||||
size_t nBytesWritten = fnDownload(pBuffer, nBytesFetched, pDownloadUserData, pStatusCode);
|
||||
if (nBytesWritten < nBytesFetched)
|
||||
{
|
||||
if (*pStatusCode == 200)
|
||||
*pStatusCode = 998;
|
||||
|
||||
bSuccess = FALSE;
|
||||
break;
|
||||
}
|
||||
@@ -453,8 +531,27 @@ static BOOL DoBlockingHttpCall(const char* sHostUrl, const char* sRequestedPage,
|
||||
bSuccess = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef RA_NOPROGRESS
|
||||
if (pProgressDialog)
|
||||
{
|
||||
if (pProgressDialog->HasUserCancelled())
|
||||
{
|
||||
bSuccess = FALSE;
|
||||
*pStatusCode = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
pProgressDialog->SetProgress(*pBytesRead, nTotalBytes);
|
||||
|
||||
if (nTotalBytes != nDefaultTotalBytes)
|
||||
SetProgressMessage(pProgressDialog, *pBytesRead, nTotalBytes);
|
||||
}
|
||||
#endif
|
||||
} while (nBytesAvailable > 0);
|
||||
} while (TRUE);
|
||||
};
|
||||
|
||||
free(pBuffer);
|
||||
}
|
||||
|
||||
WinHttpCloseHandle(hRequest);
|
||||
@@ -502,7 +599,7 @@ static BOOL DoBlockingHttpCallWithRetry(const char* sHostUrl, const char* sReque
|
||||
downloadBuffer.pBuffer = pBufferOut;
|
||||
downloadBuffer.nBufferSize = nBufferOutSize;
|
||||
|
||||
if (DoBlockingHttpCall(sHostUrl, sRequestedPage, sPostData, DownloadToBuffer, &downloadBuffer, pBytesRead, pStatusCode) != FALSE)
|
||||
if (DoBlockingHttpCall(sHostUrl, sRequestedPage, sPostData, DownloadToBuffer, &downloadBuffer, pBytesRead, pStatusCode, NULL) != FALSE)
|
||||
return TRUE;
|
||||
|
||||
if (!IsNetworkError(*pStatusCode))
|
||||
@@ -515,26 +612,54 @@ static BOOL DoBlockingHttpCallWithRetry(const char* sHostUrl, const char* sReque
|
||||
}
|
||||
|
||||
static BOOL DoBlockingHttpCallWithRetry(const char* sHostUrl, const char* sRequestedPage, const char* sPostData,
|
||||
FILE* pFile, DWORD* pBytesRead, DWORD* pStatusCode)
|
||||
FILE* pFile, DWORD* pBytesRead, DWORD* pStatusCode, const wchar_t* sMessage)
|
||||
{
|
||||
int nRetries = 4;
|
||||
do
|
||||
{
|
||||
fseek(pFile, 0, SEEK_SET);
|
||||
if (DoBlockingHttpCall(sHostUrl, sRequestedPage, sPostData, DownloadToFile, pFile, pBytesRead, pStatusCode) != FALSE)
|
||||
return TRUE;
|
||||
IProgressDialog* pProgressDialog = NULL;
|
||||
#ifndef RA_NOPROGRESS
|
||||
HRESULT hrInit = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
HRESULT hr = CoCreateInstance(CLSID_ProgressDialog, NULL, CLSCTX_INPROC_SERVER, IID_IProgressDialog, (LPVOID*)&pProgressDialog);
|
||||
|
||||
if (!IsNetworkError(*pStatusCode))
|
||||
return FALSE;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (sMessage)
|
||||
pProgressDialog->SetLine(1, sMessage, FALSE, NULL);
|
||||
pProgressDialog->StartProgressDialog(NULL, NULL, PROGDLG_NORMAL, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
--nRetries;
|
||||
} while (nRetries);
|
||||
BOOL success = FALSE;
|
||||
int nRetries = 4;
|
||||
do
|
||||
{
|
||||
fseek(pFile, 0, SEEK_SET);
|
||||
if (DoBlockingHttpCall(sHostUrl, sRequestedPage, sPostData, DownloadToFile, pFile, pBytesRead, pStatusCode, pProgressDialog) != FALSE)
|
||||
{
|
||||
success = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
if (!IsNetworkError(*pStatusCode))
|
||||
break;
|
||||
|
||||
--nRetries;
|
||||
} while (nRetries);
|
||||
|
||||
#ifndef RA_NOPROGRESS
|
||||
if (pProgressDialog)
|
||||
{
|
||||
pProgressDialog->StopProgressDialog();
|
||||
pProgressDialog->Release();
|
||||
}
|
||||
|
||||
if (hrInit == S_OK)
|
||||
CoUninitialize();
|
||||
#endif
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
#ifndef RA_UTEST
|
||||
static std::wstring GetIntegrationPath()
|
||||
static std::wstring GetIntegrationPath(const wchar_t* sFilename)
|
||||
{
|
||||
wchar_t sBuffer[2048];
|
||||
DWORD iIndex = GetModuleFileNameW(0, sBuffer, 2048);
|
||||
@@ -542,29 +667,33 @@ static std::wstring GetIntegrationPath()
|
||||
--iIndex;
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
wcscpy_s(&sBuffer[iIndex], sizeof(sBuffer)/sizeof(sBuffer[0]) - iIndex, L"RA_Integration.dll");
|
||||
wcscpy_s(&sBuffer[iIndex], sizeof(sBuffer)/sizeof(sBuffer[0]) - iIndex, sFilename);
|
||||
#else
|
||||
wcscpy(&sBuffer[iIndex], L"RA_Integration.dll");
|
||||
wcscpy(&sBuffer[iIndex], sFilename);
|
||||
#endif
|
||||
|
||||
return std::wstring(sBuffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
static void FetchIntegrationFromWeb(char* sLatestVersionUrl, DWORD* pStatusCode)
|
||||
{
|
||||
DWORD nBytesRead = 0;
|
||||
const wchar_t* sDownloadFilename = L"RA_Integration.download";
|
||||
const wchar_t* sFilename = L"RA_Integration.dll";
|
||||
const wchar_t* sOldFilename = L"RA_Integration.old";
|
||||
const std::wstring sDownloadFilename = GetIntegrationPath(RA_INT_DLL ".download");
|
||||
const std::wstring sOldFilename = GetIntegrationPath(RA_INT_DLL ".old");
|
||||
const std::wstring sNewFilename = GetIntegrationPath(RA_INT_DLL);
|
||||
std::wstring sFilename = sNewFilename;
|
||||
|
||||
#ifdef RA_X64
|
||||
if (GetFileAttributesW(sFilename.c_str()) == INVALID_FILE_ATTRIBUTES)
|
||||
sFilename = GetIntegrationPath(L"RA_Integration.dll");
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
FILE* pf;
|
||||
errno_t nErr = _wfopen_s(&pf, sDownloadFilename, L"wb");
|
||||
errno_t nErr = _wfopen_s(&pf, sDownloadFilename.c_str(), L"wb");
|
||||
#else
|
||||
FILE* pf = _wfopen(sDownloadFilename, L"wb");
|
||||
FILE* pf = _wfopen(sDownloadFilename.c_str(), L"wb");
|
||||
#endif
|
||||
|
||||
if (!pf)
|
||||
@@ -573,12 +702,13 @@ static void FetchIntegrationFromWeb(char* sLatestVersionUrl, DWORD* pStatusCode)
|
||||
wchar_t sErrBuffer[2048];
|
||||
_wcserror_s(sErrBuffer, sizeof(sErrBuffer) / sizeof(sErrBuffer[0]), nErr);
|
||||
|
||||
std::wstring sErrMsg = std::wstring(L"Unable to write ") + sOldFilename + L"\n" + sErrBuffer;
|
||||
std::wstring sErrMsg = std::wstring(L"Unable to write " RA_INT_DLL L".download\n") + sErrBuffer;
|
||||
#else
|
||||
std::wstring sErrMsg = std::wstring(L"Unable to write ") + sOldFilename + L"\n" + _wcserror(errno);
|
||||
std::wstring sErrMsg = std::wstring(L"Unable to write " RA_INT_DLL L".download\n") + _wcserror(errno);
|
||||
#endif
|
||||
|
||||
MessageBoxW(nullptr, sErrMsg.c_str(), L"Error", MB_OK | MB_ICONERROR);
|
||||
*pStatusCode = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -594,36 +724,36 @@ static void FetchIntegrationFromWeb(char* sLatestVersionUrl, DWORD* pStatusCode)
|
||||
}
|
||||
*pSplit++ = '\0';
|
||||
|
||||
if (DoBlockingHttpCallWithRetry(sLatestVersionUrl, pSplit, nullptr, pf, &nBytesRead, pStatusCode))
|
||||
if (DoBlockingHttpCallWithRetry(sLatestVersionUrl, pSplit, nullptr, pf, &nBytesRead, pStatusCode, "Downloading " RA_INT_DLL))
|
||||
{
|
||||
fclose(pf);
|
||||
|
||||
/* wait up to one second for the DLL to actually be released - sometimes it's not immediate */
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (GetModuleHandleW(sFilename) == nullptr)
|
||||
if (GetModuleHandleW(sFilename.c_str()) == nullptr)
|
||||
break;
|
||||
|
||||
Sleep(100);
|
||||
}
|
||||
|
||||
// delete the last old dll if it's still present
|
||||
DeleteFileW(sOldFilename);
|
||||
DeleteFileW(sOldFilename.c_str());
|
||||
|
||||
// if there's a dll present, rename it
|
||||
if (GetFileAttributesW(sFilename) != INVALID_FILE_ATTRIBUTES &&
|
||||
!MoveFileW(sFilename, sOldFilename))
|
||||
if (GetFileAttributesW(sFilename.c_str()) != INVALID_FILE_ATTRIBUTES &&
|
||||
!MoveFileW(sFilename.c_str(), sOldFilename.c_str()))
|
||||
{
|
||||
MessageBoxW(nullptr, L"Could not rename old dll", L"Error", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
// rename the download to be the dll
|
||||
else if (!MoveFileW(sDownloadFilename, sFilename))
|
||||
else if (!MoveFileW(sDownloadFilename.c_str(), sNewFilename.c_str()))
|
||||
{
|
||||
MessageBoxW(nullptr, L"Could not rename new dll", L"Error", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
|
||||
// delete the old dll
|
||||
DeleteFileW(sOldFilename);
|
||||
DeleteFileW(sOldFilename.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -631,8 +761,6 @@ static void FetchIntegrationFromWeb(char* sLatestVersionUrl, DWORD* pStatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//Returns the last Win32 error, in string format. Returns an empty string if there is no error.
|
||||
static std::string GetLastErrorAsString()
|
||||
{
|
||||
@@ -657,9 +785,15 @@ static const char* CCONV _RA_InstallIntegration()
|
||||
{
|
||||
SetErrorMode(0);
|
||||
|
||||
std::wstring sIntegrationPath = GetIntegrationPath();
|
||||
std::wstring sIntegrationPath = GetIntegrationPath(RA_INT_DLL);
|
||||
|
||||
DWORD dwAttrib = GetFileAttributesW(sIntegrationPath.c_str());
|
||||
#ifdef RA_X64
|
||||
if (dwAttrib == INVALID_FILE_ATTRIBUTES) {
|
||||
sIntegrationPath = GetIntegrationPath(L"RA_Integration.dll");
|
||||
dwAttrib = GetFileAttributesW(sIntegrationPath.c_str());
|
||||
}
|
||||
#endif
|
||||
if (dwAttrib == INVALID_FILE_ATTRIBUTES)
|
||||
return "0.0";
|
||||
|
||||
@@ -667,7 +801,23 @@ static const char* CCONV _RA_InstallIntegration()
|
||||
if (g_hRADLL == nullptr)
|
||||
{
|
||||
char buffer[1024];
|
||||
sprintf_s(buffer, 1024, "Could not load RA_Integration.dll: %d\n%s\n", ::GetLastError(), GetLastErrorAsString().c_str());
|
||||
if (::GetLastError() == ERROR_BAD_EXE_FORMAT)
|
||||
{
|
||||
#ifdef RA_X64
|
||||
sprintf_s(buffer, sizeof(buffer), "Could not load RA_Integration-x64.dll (error %d)\nAre you trying to load the 32-bit version?\n", ::GetLastError());
|
||||
#else
|
||||
sprintf_s(buffer, sizeof(buffer), "Could not load RA_Integration.dll (error %d)\nAre you trying to load the 64-bit version?\n", ::GetLastError());
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef RA_X64
|
||||
sprintf_s(buffer, sizeof(buffer), "Could not load RA_Integration-x64.dll (error %d)\n%s\n", ::GetLastError(), GetLastErrorAsString().c_str());
|
||||
#else
|
||||
sprintf_s(buffer, sizeof(buffer), "Could not load RA_Integration.dll (error %d)\n%s\n", ::GetLastError(), GetLastErrorAsString().c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
MessageBoxA(nullptr, buffer, "Warning", MB_OK | MB_ICONWARNING);
|
||||
|
||||
return "0.0";
|
||||
@@ -876,7 +1026,7 @@ static void RA_InitCommon(HWND hMainHWND, int nEmulatorID, const char* sClientNa
|
||||
GetJsonField(buffer, "LatestVersion", sVersionBuffer, sizeof(sVersionBuffer));
|
||||
const unsigned long long nLatestDLLVer = ParseVersion(sVersionBuffer);
|
||||
|
||||
#if defined(_M_X64) || defined(__amd64__)
|
||||
#ifdef RA_X64
|
||||
GetJsonField(buffer, "LatestVersionUrlX64", sLatestVersionUrl, sizeof(sLatestVersionUrl));
|
||||
#else
|
||||
GetJsonField(buffer, "LatestVersionUrl", sLatestVersionUrl, sizeof(sLatestVersionUrl));
|
||||
@@ -930,16 +1080,18 @@ static void RA_InitCommon(HWND hMainHWND, int nEmulatorID, const char* sClientNa
|
||||
|
||||
if (nMBReply == IDYES)
|
||||
{
|
||||
//FetchIntegrationFromWeb(sLatestVersionUrl, &nStatusCode);
|
||||
nStatusCode = 0;
|
||||
FetchIntegrationFromWeb(sLatestVersionUrl, &nStatusCode);
|
||||
|
||||
if (nStatusCode == 200)
|
||||
nVerInstalled = ParseVersion(_RA_InstallIntegration());
|
||||
|
||||
if (nVerInstalled < nLatestDLLVer)
|
||||
if (nStatusCode != 0) // 0 indicates an error was already reported
|
||||
{
|
||||
sprintf_s(buffer, sizeof(buffer), "Failed to update toolset (status code %u).", nStatusCode);
|
||||
MessageBoxA(hMainHWND, buffer, "Error", MB_OK | MB_ICONERROR);
|
||||
if (nStatusCode == 200)
|
||||
nVerInstalled = ParseVersion(_RA_InstallIntegration());
|
||||
|
||||
if (nVerInstalled < nLatestDLLVer)
|
||||
{
|
||||
sprintf_s(buffer, sizeof(buffer), "Failed to update toolset (status code %u).", nStatusCode);
|
||||
MessageBoxA(hMainHWND, buffer, "Error", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
-91
@@ -1,91 +0,0 @@
|
||||
add_library(pcsx2-rapidyaml
|
||||
include/c4/base64.hpp
|
||||
include/c4/blob.hpp
|
||||
include/c4/charconv.hpp
|
||||
include/c4/compiler.hpp
|
||||
include/c4/config.hpp
|
||||
include/c4/cpu.hpp
|
||||
include/c4/dump.hpp
|
||||
include/c4/error.hpp
|
||||
include/c4/export.hpp
|
||||
include/c4/format.hpp
|
||||
include/c4/language.hpp
|
||||
include/c4/memory_util.hpp
|
||||
include/c4/platform.hpp
|
||||
include/c4/preprocessor.hpp
|
||||
include/c4/std/std.hpp
|
||||
include/c4/std/std_fwd.hpp
|
||||
include/c4/std/string.hpp
|
||||
include/c4/std/string_fwd.hpp
|
||||
include/c4/std/string_view.hpp
|
||||
include/c4/std/tuple.hpp
|
||||
include/c4/std/vector.hpp
|
||||
include/c4/std/vector_fwd.hpp
|
||||
include/c4/substr.hpp
|
||||
include/c4/substr_fwd.hpp
|
||||
include/c4/szconv.hpp
|
||||
include/c4/types.hpp
|
||||
include/c4/utf.hpp
|
||||
include/c4/windows.hpp
|
||||
include/c4/windows_pop.hpp
|
||||
include/c4/windows_push.hpp
|
||||
include/c4/yml/common.hpp
|
||||
include/c4/yml/detail/dbgprint.hpp
|
||||
include/c4/yml/detail/stack.hpp
|
||||
include/c4/yml/emit.def.hpp
|
||||
include/c4/yml/emit.hpp
|
||||
include/c4/yml/event_handler_stack.hpp
|
||||
include/c4/yml/event_handler_tree.hpp
|
||||
include/c4/yml/filter_processor.hpp
|
||||
include/c4/yml/fwd.hpp
|
||||
include/c4/yml/export.hpp
|
||||
include/c4/yml/node.hpp
|
||||
include/c4/yml/node_type.hpp
|
||||
include/c4/yml/parse.hpp
|
||||
include/c4/yml/parse_engine.def.hpp
|
||||
include/c4/yml/parse_engine.hpp
|
||||
include/c4/yml/parser_state.hpp
|
||||
include/c4/yml/reference_resolver.hpp
|
||||
include/c4/yml/preprocess.hpp
|
||||
include/c4/yml/std/map.hpp
|
||||
include/c4/yml/std/std.hpp
|
||||
include/c4/yml/std/string.hpp
|
||||
include/c4/yml/std/vector.hpp
|
||||
include/c4/yml/tag.hpp
|
||||
include/c4/yml/tree.hpp
|
||||
include/c4/yml/version.hpp
|
||||
include/c4/yml/writer.hpp
|
||||
include/c4/yml/yml.hpp
|
||||
include/ryml.hpp
|
||||
include/ryml_std.hpp
|
||||
src/c4/base64.cpp
|
||||
src/c4/error.cpp
|
||||
src/c4/format.cpp
|
||||
src/c4/language.cpp
|
||||
src/c4/memory_util.cpp
|
||||
src/c4/utf.cpp
|
||||
src/c4/yml/common.cpp
|
||||
src/c4/yml/node.cpp
|
||||
src/c4/yml/parse.cpp
|
||||
src/c4/yml/preprocess.cpp
|
||||
src/c4/yml/tree.cpp
|
||||
src/c4/yml/node_type.cpp
|
||||
src/c4/yml/reference_resolver.cpp
|
||||
src/c4/yml/tag.cpp
|
||||
src/c4/yml/version.cpp
|
||||
)
|
||||
|
||||
target_include_directories(pcsx2-rapidyaml PRIVATE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../fast_float/include"
|
||||
)
|
||||
target_include_directories(pcsx2-rapidyaml INTERFACE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
)
|
||||
|
||||
target_compile_definitions(pcsx2-rapidyaml PUBLIC
|
||||
"C4_NO_DEBUG_BREAK"
|
||||
)
|
||||
|
||||
add_library(rapidyaml::rapidyaml ALIAS pcsx2-rapidyaml)
|
||||
-141
@@ -1,141 +0,0 @@
|
||||
#ifndef _C4_BASE64_HPP_
|
||||
#define _C4_BASE64_HPP_
|
||||
|
||||
/** @file base64.hpp encoding/decoding for base64.
|
||||
* @see https://en.wikipedia.org/wiki/Base64
|
||||
* @see https://www.base64encode.org/
|
||||
* */
|
||||
|
||||
#include "c4/charconv.hpp"
|
||||
#include "c4/blob.hpp"
|
||||
|
||||
namespace c4 {
|
||||
|
||||
/** @defgroup doc_base64 Base64 encoding/decoding
|
||||
* @see https://en.wikipedia.org/wiki/Base64
|
||||
* @see https://www.base64encode.org/
|
||||
* @{ */
|
||||
|
||||
/** check that the given buffer is a valid base64 encoding
|
||||
* @see https://en.wikipedia.org/wiki/Base64 */
|
||||
C4CORE_EXPORT bool base64_valid(csubstr encoded);
|
||||
|
||||
|
||||
/** base64-encode binary data.
|
||||
* @param encoded [out] output buffer for encoded data
|
||||
* @param data [in] the input buffer with the binary data
|
||||
*
|
||||
* @return the number of bytes needed to return the output (ie the
|
||||
* required size for @p encoded). No writes occur beyond the end of
|
||||
* the output buffer, so it is safe to do a speculative call where the
|
||||
* encoded buffer is empty, or maybe too small. The caller should
|
||||
* ensure that the returned size is smaller than the size of the
|
||||
* encoded buffer.
|
||||
*
|
||||
* @note the result depends on endianness. If transfer between
|
||||
* little/big endian systems is desired, the caller should normalize
|
||||
* @p data before encoding.
|
||||
*
|
||||
* @see https://en.wikipedia.org/wiki/Base64 */
|
||||
C4CORE_EXPORT size_t base64_encode(substr encoded, cblob data);
|
||||
|
||||
|
||||
/** decode the base64 encoding in the given buffer
|
||||
* @param encoded [in] the encoded base64
|
||||
* @param data [out] the output buffer
|
||||
*
|
||||
* @return the number of bytes needed to return the output (ie the
|
||||
* required size for @p data). No writes occur beyond the end of the
|
||||
* output buffer, so it is safe to do a speculative call where the
|
||||
* data buffer is empty, or maybe too small. The caller should ensure
|
||||
* that the returned size is smaller than the size of the data buffer.
|
||||
*
|
||||
* @note the result depends on endianness. If transfer between
|
||||
* little/big endian systems is desired, the caller should normalize
|
||||
* @p data after decoding.
|
||||
*
|
||||
* @see https://en.wikipedia.org/wiki/Base64 */
|
||||
C4CORE_EXPORT size_t base64_decode(csubstr encoded, blob data);
|
||||
|
||||
/** @} */ // base64
|
||||
|
||||
namespace fmt {
|
||||
|
||||
/** @addtogroup doc_format_specifiers
|
||||
* @{ */
|
||||
|
||||
/** @defgroup doc_base64_fmt Base64
|
||||
* @{ */
|
||||
|
||||
template<typename CharOrConstChar>
|
||||
struct base64_wrapper_
|
||||
{
|
||||
blob_<CharOrConstChar> data;
|
||||
base64_wrapper_() : data() {}
|
||||
base64_wrapper_(blob_<CharOrConstChar> blob) : data(blob) {}
|
||||
};
|
||||
/** a tag type to mark a payload as base64-encoded */
|
||||
using const_base64_wrapper = base64_wrapper_<cbyte>;
|
||||
/** a tag type to mark a payload to be encoded as base64 */
|
||||
using base64_wrapper = base64_wrapper_<byte>;
|
||||
|
||||
|
||||
/** mark a variable to be written in base64 format */
|
||||
template<class ...Args>
|
||||
C4_ALWAYS_INLINE const_base64_wrapper cbase64(Args const& C4_RESTRICT ...args)
|
||||
{
|
||||
return const_base64_wrapper(cblob(args...));
|
||||
}
|
||||
/** mark a csubstr to be written in base64 format */
|
||||
C4_ALWAYS_INLINE const_base64_wrapper cbase64(csubstr s)
|
||||
{
|
||||
return const_base64_wrapper(cblob(s.str, s.len));
|
||||
}
|
||||
/** mark a variable to be written in base64 format */
|
||||
template<class ...Args>
|
||||
C4_ALWAYS_INLINE const_base64_wrapper base64(Args const& C4_RESTRICT ...args)
|
||||
{
|
||||
return const_base64_wrapper(cblob(args...));
|
||||
}
|
||||
/** mark a csubstr to be written in base64 format */
|
||||
C4_ALWAYS_INLINE const_base64_wrapper base64(csubstr s)
|
||||
{
|
||||
return const_base64_wrapper(cblob(s.str, s.len));
|
||||
}
|
||||
|
||||
/** mark a variable to be read in base64 format */
|
||||
template<class ...Args>
|
||||
C4_ALWAYS_INLINE base64_wrapper base64(Args &... args)
|
||||
{
|
||||
return base64_wrapper(blob(args...));
|
||||
}
|
||||
/** mark a variable to be read in base64 format */
|
||||
C4_ALWAYS_INLINE base64_wrapper base64(substr s)
|
||||
{
|
||||
return base64_wrapper(blob(s.str, s.len));
|
||||
}
|
||||
|
||||
/** @} */ // base64_fmt
|
||||
|
||||
/** @} */ // format_specifiers
|
||||
|
||||
} // namespace fmt
|
||||
|
||||
|
||||
/** write a variable in base64 format
|
||||
* @ingroup doc_to_chars */
|
||||
inline size_t to_chars(substr buf, fmt::const_base64_wrapper b)
|
||||
{
|
||||
return base64_encode(buf, b.data);
|
||||
}
|
||||
|
||||
/** read a variable in base64 format
|
||||
* @ingroup doc_from_chars */
|
||||
inline size_t from_chars(csubstr buf, fmt::base64_wrapper *b)
|
||||
{
|
||||
return base64_decode(buf, b->data);
|
||||
}
|
||||
|
||||
} // namespace c4
|
||||
|
||||
#endif /* _C4_BASE64_HPP_ */
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
#ifndef _C4_BLOB_HPP_
|
||||
#define _C4_BLOB_HPP_
|
||||
|
||||
#include "c4/types.hpp"
|
||||
#include "c4/error.hpp"
|
||||
|
||||
/** @file blob.hpp Mutable and immutable binary data blobs.
|
||||
*/
|
||||
|
||||
namespace c4 {
|
||||
|
||||
template<class T>
|
||||
struct blob_;
|
||||
|
||||
namespace detail {
|
||||
template<class T> struct is_blob_type : std::integral_constant<bool, false> {};
|
||||
template<class T> struct is_blob_type<blob_<T>> : std::integral_constant<bool, true> {};
|
||||
template<class T> struct is_blob_value_type : std::integral_constant<bool, (std::is_fundamental<T>::value || std::is_trivially_copyable<T>::value)> {};
|
||||
} // namespace
|
||||
|
||||
// NOLINTBEGIN(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
|
||||
|
||||
template<class T>
|
||||
struct blob_
|
||||
{
|
||||
static_assert(std::is_same<T, byte>::value || std::is_same<T, cbyte>::value, "must be either byte or cbyte");
|
||||
static_assert(sizeof(T) == 1u, "must be either byte or cbyte");
|
||||
|
||||
public:
|
||||
|
||||
T * buf;
|
||||
size_t len;
|
||||
|
||||
public:
|
||||
|
||||
C4_ALWAYS_INLINE blob_() noexcept = default;
|
||||
C4_ALWAYS_INLINE blob_(blob_ const& that) noexcept = default;
|
||||
C4_ALWAYS_INLINE blob_(blob_ && that) noexcept = default;
|
||||
C4_ALWAYS_INLINE blob_& operator=(blob_ && that) noexcept = default;
|
||||
C4_ALWAYS_INLINE blob_& operator=(blob_ const& that) noexcept = default;
|
||||
|
||||
template<class U, class=typename std::enable_if<std::is_const<T>::value && std::is_same<typename std::add_const<U>::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_(blob_<U> const& that) noexcept : buf(that.buf), len(that.len) {} // NOLINT
|
||||
template<class U, class=typename std::enable_if<std::is_const<T>::value && std::is_same<typename std::add_const<U>::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_(blob_<U> && that) noexcept : buf(that.buf), len(that.len) {} // NOLINT
|
||||
template<class U, class=typename std::enable_if<std::is_const<T>::value && std::is_same<typename std::add_const<U>::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_& operator=(blob_<U> && that) noexcept { buf = that.buf; len = that.len; } // NOLINT
|
||||
template<class U, class=typename std::enable_if<std::is_const<T>::value && std::is_same<typename std::add_const<U>::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_& operator=(blob_<U> const& that) noexcept { buf = that.buf; len = that.len; } // NOLINT
|
||||
|
||||
C4_ALWAYS_INLINE blob_(void *ptr, size_t n) noexcept : buf(reinterpret_cast<T*>(ptr)), len(n) {} // NOLINT
|
||||
C4_ALWAYS_INLINE blob_(void const *ptr, size_t n) noexcept : buf(reinterpret_cast<T*>(ptr)), len(n) {} // NOLINT
|
||||
|
||||
#define _C4_REQUIRE_BLOBTYPE(ty) class=typename std::enable_if<((!detail::is_blob_type<ty>::value) && (detail::is_blob_value_type<ty>::value)), T>::type
|
||||
template<class U, _C4_REQUIRE_BLOBTYPE(U)> C4_ALWAYS_INLINE blob_(U &var) noexcept : buf(reinterpret_cast<T*>(&var)), len(sizeof(U)) {} // NOLINT
|
||||
template<class U, _C4_REQUIRE_BLOBTYPE(U)> C4_ALWAYS_INLINE blob_(U *ptr, size_t n) noexcept : buf(reinterpret_cast<T*>(ptr)), len(sizeof(U) * n) { C4_ASSERT(is_aligned(ptr)); } // NOLINT
|
||||
template<class U, _C4_REQUIRE_BLOBTYPE(U)> C4_ALWAYS_INLINE blob_& operator= (U &var) noexcept { buf = reinterpret_cast<T*>(&var); len = sizeof(U); return *this; } // NOLINT
|
||||
template<class U, size_t N, _C4_REQUIRE_BLOBTYPE(U)> C4_ALWAYS_INLINE blob_(U (&arr)[N]) noexcept : buf(reinterpret_cast<T*>(arr)), len(sizeof(U) * N) {} // NOLINT
|
||||
template<class U, size_t N, _C4_REQUIRE_BLOBTYPE(U)> C4_ALWAYS_INLINE blob_& operator= (U (&arr)[N]) noexcept { buf = reinterpret_cast<T*>(arr); len = sizeof(U) * N; return *this; } // NOLINT
|
||||
#undef _C4_REQUIRE_BLOBTYPE
|
||||
};
|
||||
|
||||
// NOLINTEND(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
|
||||
|
||||
/** an immutable binary blob */
|
||||
using cblob = blob_<cbyte>;
|
||||
/** a mutable binary blob */
|
||||
using blob = blob_< byte>;
|
||||
|
||||
C4_MUST_BE_TRIVIAL_COPY(blob);
|
||||
C4_MUST_BE_TRIVIAL_COPY(cblob);
|
||||
|
||||
} // namespace c4
|
||||
|
||||
#endif // _C4_BLOB_HPP_
|
||||
-168
@@ -1,168 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
Very good intro:
|
||||
@see https://code.msdn.microsoft.com/windowsdesktop/Writing-type-visualizers-2eae77a2
|
||||
See also:
|
||||
@see http://blogs.msdn.com/b/vcblog/archive/2013/06/28/using-visual-studio-2013-to-write-maintainable-native-visualizations-natvis.aspx?PageIndex=2
|
||||
@see http://blogs.msdn.com/b/vcblog/archive/2015/09/28/debug-visualizers-in-visual-c-2015.aspx
|
||||
@see http://stackoverflow.com/questions/36883414/limit-display-of-char-in-natvis-file-to-specific-length
|
||||
-->
|
||||
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
|
||||
<Type Name="c4::basic_substring<*>">
|
||||
<DisplayString>{str,[len]} (sz={len})</DisplayString>
|
||||
<StringView>str,[len]</StringView>
|
||||
<Expand>
|
||||
<Item Name="[size]">len</Item>
|
||||
<ArrayItems>
|
||||
<Size>len</Size>
|
||||
<ValuePointer>str</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
<Type Name="c4::span<*>">
|
||||
<DisplayString>{m_ptr,[m_size]} (sz={m_size})</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[size]">m_size</Item>
|
||||
<ArrayItems>
|
||||
<Size>m_size</Size>
|
||||
<ValuePointer>m_ptr</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="c4::spanrs<*>">
|
||||
<DisplayString>{m_ptr,[m_size]} (sz={m_size}, cap={m_capacity})</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[size]">m_size</Item>
|
||||
<Item Name="[capacity]">m_capacity</Item>
|
||||
<ArrayItems>
|
||||
<Size>m_size</Size>
|
||||
<ValuePointer>m_ptr</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<!-- display span<char>/span<const char> as a string too -->
|
||||
<Type Name="c4::span<char,*>">
|
||||
<DisplayString>{m_ptr,[m_size]} (sz={m_size})</DisplayString>
|
||||
<StringView>m_ptr,[m_size]</StringView>
|
||||
<Expand>
|
||||
<Item Name="[size]">m_size</Item>
|
||||
<ArrayItems>
|
||||
<Size>m_size</Size>
|
||||
<ValuePointer>m_ptr</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="c4::span<const char,*>">
|
||||
<DisplayString>{m_ptr,[m_size]} (sz={m_size})</DisplayString>
|
||||
<StringView>m_ptr,[m_size]</StringView>
|
||||
<Expand>
|
||||
<Item Name="[size]">m_size</Item>
|
||||
<ArrayItems>
|
||||
<Size>m_size</Size>
|
||||
<ValuePointer>m_ptr</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<!-- display spanrs<char>/spanrs<const char> as a string too -->
|
||||
<Type Name="c4::spanrs<char,*>">
|
||||
<DisplayString>{m_ptr,[m_size]} (sz={m_size}, cap={m_capacity})</DisplayString>
|
||||
<StringView>m_ptr,[m_size]</StringView>
|
||||
<Expand>
|
||||
<Item Name="[size]">m_size</Item>
|
||||
<Item Name="[capacity]">m_capacity</Item>
|
||||
<ArrayItems>
|
||||
<Size>m_size</Size>
|
||||
<ValuePointer>m_ptr</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="c4::spanrs<const char,*>">
|
||||
<DisplayString>{m_ptr,[m_size]} (sz={m_size}, cap={m_capacity})</DisplayString>
|
||||
<StringView>m_ptr,[m_size]</StringView>
|
||||
<Expand>
|
||||
<Item Name="[size]">m_size</Item>
|
||||
<Item Name="[capacity]">m_capacity</Item>
|
||||
<ArrayItems>
|
||||
<Size>m_size</Size>
|
||||
<ValuePointer>m_ptr</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
<!-- =========================================================================================== -->
|
||||
<Type Name="c4::string_impl<*,*,*,*>">
|
||||
<DisplayString>{(($T3*)this)->m_str,[(($T3*)this)->m_size]} (sz={(($T3*)this)->m_size})</DisplayString>
|
||||
<StringView>(($T3*)this)->m_str,[(($T3*)this)->m_size]</StringView>
|
||||
<Expand>
|
||||
<Synthetic Name="m_str">
|
||||
<DisplayString>{(($T3*)this)->m_str,[(($T3*)this)->m_size]}</DisplayString>
|
||||
<StringView>(($T3*)this)->m_str,[(($T3*)this)->m_size]</StringView>
|
||||
</Synthetic>
|
||||
<Synthetic Name="m_size">
|
||||
<DisplayString>{(($T3*)this)->m_size}</DisplayString>
|
||||
</Synthetic>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="c4::basic_substring<*,*>">
|
||||
<DisplayString>{m_str,[m_size]} (sz={m_size})</DisplayString>
|
||||
<StringView>m_str,[m_size]</StringView>
|
||||
<Expand>
|
||||
<Synthetic Name="[size]">
|
||||
<DisplayString>{m_size}</DisplayString>
|
||||
</Synthetic>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="c4::basic_substringrs<*,*>">
|
||||
<DisplayString>{m_str,[m_size]} (sz={m_size},cap={m_capacity})</DisplayString>
|
||||
<StringView>m_str,[m_size]</StringView>
|
||||
<Expand>
|
||||
<Synthetic Name="[size]">
|
||||
<DisplayString>{m_size}</DisplayString>
|
||||
</Synthetic>
|
||||
<Synthetic Name="[capacity]">
|
||||
<DisplayString>{m_capacity}</DisplayString>
|
||||
</Synthetic>
|
||||
<Synthetic Name="[full]">
|
||||
<DisplayString>{m_str,[m_capacity]}</DisplayString>
|
||||
<StringView>m_str,[m_capacity]</StringView>
|
||||
</Synthetic>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="c4::basic_string<*,*,*>">
|
||||
<DisplayString>{m_str,[m_size]} (sz={m_size},cap={m_capacity})</DisplayString>
|
||||
<StringView>m_str,[m_size]</StringView>
|
||||
<Expand>
|
||||
<Synthetic Name="[size]">
|
||||
<DisplayString>{m_size}</DisplayString>
|
||||
</Synthetic>
|
||||
<Synthetic Name="[full]">
|
||||
<DisplayString>{m_str,[m_capacity]}</DisplayString>
|
||||
<StringView>m_str,[m_capacity]</StringView>
|
||||
</Synthetic>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
<!-- enum symbols -->
|
||||
<Type Name="c4::EnumSymbols<*>::Sym">
|
||||
<DisplayString>{value} - {name}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[value]">value</Item>
|
||||
<Item Name="[name]">name</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="c4::EnumSymbols<*>">
|
||||
<DisplayString>{m_symbols,[m_num]} (sz={m_num})</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[size]">m_num</Item>
|
||||
<ArrayItems>
|
||||
<Size>m_num</Size>
|
||||
<ValuePointer>m_symbols</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
</AutoVisualizer>
|
||||
-2670
File diff suppressed because it is too large
Load Diff
-120
@@ -1,120 +0,0 @@
|
||||
#ifndef _C4_COMPILER_HPP_
|
||||
#define _C4_COMPILER_HPP_
|
||||
|
||||
/** @file compiler.hpp Provides compiler information macros
|
||||
* @ingroup basic_headers */
|
||||
|
||||
#include "c4/platform.hpp"
|
||||
|
||||
// Compilers:
|
||||
// C4_MSVC
|
||||
// Visual Studio 2022: MSVC++ 17, 1930
|
||||
// Visual Studio 2019: MSVC++ 16, 1920
|
||||
// Visual Studio 2017: MSVC++ 15
|
||||
// Visual Studio 2015: MSVC++ 14
|
||||
// Visual Studio 2013: MSVC++ 13
|
||||
// Visual Studio 2013: MSVC++ 12
|
||||
// Visual Studio 2012: MSVC++ 11
|
||||
// Visual Studio 2010: MSVC++ 10
|
||||
// Visual Studio 2008: MSVC++ 09
|
||||
// Visual Studio 2005: MSVC++ 08
|
||||
// C4_CLANG
|
||||
// C4_GCC
|
||||
// C4_ICC (intel compiler)
|
||||
/** @see http://sourceforge.net/p/predef/wiki/Compilers/ for a list of compiler identifier macros */
|
||||
/** @see https://msdn.microsoft.com/en-us/library/b0084kay.aspx for VS2013 predefined macros */
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
# define C4_MSVC
|
||||
# define C4_MSVC_VERSION_2022 17
|
||||
# define C4_MSVC_VERSION_2019 16
|
||||
# define C4_MSVC_VERSION_2017 15
|
||||
# define C4_MSVC_VERSION_2015 14
|
||||
# define C4_MSVC_VERSION_2013 12
|
||||
# define C4_MSVC_VERSION_2012 11
|
||||
# if _MSC_VER >= 1930
|
||||
# define C4_MSVC_VERSION C4_MSVC_VERSION_2022 // visual studio 2022
|
||||
# define C4_MSVC_2022
|
||||
# elif _MSC_VER >= 1920
|
||||
# define C4_MSVC_VERSION C4_MSVC_VERSION_2019 // visual studio 2019
|
||||
# define C4_MSVC_2019
|
||||
# elif _MSC_VER >= 1910
|
||||
# define C4_MSVC_VERSION C4_MSVC_VERSION_2017 // visual studio 2017
|
||||
# define C4_MSVC_2017
|
||||
# elif _MSC_VER == 1900
|
||||
# define C4_MSVC_VERSION C4_MSVC_VERSION_2015 // visual studio 2015
|
||||
# define C4_MSVC_2015
|
||||
# elif _MSC_VER == 1800
|
||||
# error "MSVC version not supported"
|
||||
# define C4_MSVC_VERSION C4_MSVC_VERSION_2013 // visual studio 2013
|
||||
# define C4_MSVC_2013
|
||||
# elif _MSC_VER == 1700
|
||||
# error "MSVC version not supported"
|
||||
# define C4_MSVC_VERSION C4_MSVC_VERSION_2012 // visual studio 2012
|
||||
# define C4_MSVC_2012
|
||||
# elif _MSC_VER == 1600
|
||||
# error "MSVC version not supported"
|
||||
# define C4_MSVC_VERSION 10 // visual studio 2010
|
||||
# define C4_MSVC_2010
|
||||
# elif _MSC_VER == 1500
|
||||
# error "MSVC version not supported"
|
||||
# define C4_MSVC_VERSION 09 // visual studio 2008
|
||||
# define C4_MSVC_2008
|
||||
# elif _MSC_VER == 1400
|
||||
# error "MSVC version not supported"
|
||||
# define C4_MSVC_VERSION 08 // visual studio 2005
|
||||
# define C4_MSVC_2005
|
||||
# else
|
||||
# error "MSVC version not supported"
|
||||
# endif // _MSC_VER
|
||||
#else
|
||||
# define C4_MSVC_VERSION 0 // visual studio not present
|
||||
# define C4_GCC_LIKE
|
||||
# ifdef __INTEL_COMPILER // check ICC before checking GCC, as ICC defines __GNUC__ too
|
||||
# define C4_ICC
|
||||
# define C4_ICC_VERSION __INTEL_COMPILER
|
||||
# elif defined(__APPLE_CC__)
|
||||
# define C4_XCODE
|
||||
# if defined(__clang__)
|
||||
# define C4_CLANG
|
||||
# ifndef __apple_build_version__
|
||||
# define C4_CLANG_VERSION C4_VERSION_ENCODED(__clang_major__, __clang_minor__, __clang_patchlevel__)
|
||||
# else
|
||||
# define C4_CLANG_VERSION __apple_build_version__
|
||||
# endif
|
||||
# else
|
||||
# define C4_XCODE_VERSION __APPLE_CC__
|
||||
# endif
|
||||
# elif defined(__clang__)
|
||||
# define C4_CLANG
|
||||
# ifndef __apple_build_version__
|
||||
# define C4_CLANG_VERSION C4_VERSION_ENCODED(__clang_major__, __clang_minor__, __clang_patchlevel__)
|
||||
# else
|
||||
# define C4_CLANG_VERSION __apple_build_version__
|
||||
# endif
|
||||
# elif defined(__GNUC__)
|
||||
# ifdef __MINGW32__
|
||||
# define C4_MINGW
|
||||
# endif
|
||||
# define C4_GCC
|
||||
# if defined(__GNUC_PATCHLEVEL__)
|
||||
# define C4_GCC_VERSION C4_VERSION_ENCODED(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
|
||||
# else
|
||||
# define C4_GCC_VERSION C4_VERSION_ENCODED(__GNUC__, __GNUC_MINOR__, 0)
|
||||
# endif
|
||||
# if __GNUC__ < 5
|
||||
# if __GNUC__ == 4 && __GNUC_MINOR__ >= 8
|
||||
// provided by cmake sub-project
|
||||
# include "c4/gcc-4.8.hpp"
|
||||
# else
|
||||
// we do not support GCC < 4.8:
|
||||
// * misses std::is_trivially_copyable
|
||||
// * misses std::align
|
||||
// * -Wshadow has false positives when a local function parameter has the same name as a method
|
||||
# error "GCC < 4.8 is not supported"
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif // defined(C4_WIN) && defined(_MSC_VER)
|
||||
|
||||
#endif /* _C4_COMPILER_HPP_ */
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
#ifndef _C4_CONFIG_HPP_
|
||||
#define _C4_CONFIG_HPP_
|
||||
|
||||
/** @defgroup basic_headers Basic headers
|
||||
* @brief Headers providing basic macros, platform+cpu+compiler information,
|
||||
* C++ facilities and basic typedefs. */
|
||||
|
||||
/** @file config.hpp Contains configuration defines and includes the basic_headers.
|
||||
* @ingroup basic_headers */
|
||||
|
||||
//#define C4_DEBUG
|
||||
|
||||
#define C4_ERROR_SHOWS_FILELINE
|
||||
//#define C4_ERROR_SHOWS_FUNC
|
||||
//#define C4_ERROR_THROWS_EXCEPTION
|
||||
//#define C4_NO_ALLOC_DEFAULTS
|
||||
//#define C4_REDEFINE_CPPNEW
|
||||
|
||||
#ifndef C4_SIZE_TYPE
|
||||
# define C4_SIZE_TYPE size_t
|
||||
#endif
|
||||
|
||||
#ifndef C4_STR_SIZE_TYPE
|
||||
# define C4_STR_SIZE_TYPE C4_SIZE_TYPE
|
||||
#endif
|
||||
|
||||
#ifndef C4_TIME_TYPE
|
||||
# define C4_TIME_TYPE double
|
||||
#endif
|
||||
|
||||
#include "c4/export.hpp"
|
||||
#include "c4/preprocessor.hpp"
|
||||
#include "c4/platform.hpp"
|
||||
#include "c4/cpu.hpp"
|
||||
#include "c4/compiler.hpp"
|
||||
#include "c4/language.hpp"
|
||||
#include "c4/types.hpp"
|
||||
|
||||
#endif // _C4_CONFIG_HPP_
|
||||
-205
@@ -1,205 +0,0 @@
|
||||
#ifndef _C4_CPU_HPP_
|
||||
#define _C4_CPU_HPP_
|
||||
|
||||
/** @file cpu.hpp Provides processor information macros
|
||||
* @ingroup basic_headers */
|
||||
|
||||
// see also https://sourceforge.net/p/predef/wiki/Architectures/
|
||||
// see also https://sourceforge.net/p/predef/wiki/Endianness/
|
||||
// see also https://github.com/googlesamples/android-ndk/blob/android-mk/hello-jni/jni/hello-jni.c
|
||||
// see also http://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/global/qprocessordetection.h
|
||||
|
||||
#ifdef __ORDER_LITTLE_ENDIAN__
|
||||
# define _C4EL __ORDER_LITTLE_ENDIAN__
|
||||
#else
|
||||
# define _C4EL 1234
|
||||
#endif
|
||||
|
||||
#ifdef __ORDER_BIG_ENDIAN__
|
||||
# define _C4EB __ORDER_BIG_ENDIAN__
|
||||
#else
|
||||
# define _C4EB 4321
|
||||
#endif
|
||||
|
||||
// mixed byte order (eg, PowerPC or ia64)
|
||||
#define _C4EM 1111 // NOLINT
|
||||
|
||||
|
||||
// NOTE: to find defined macros in a platform,
|
||||
// g++ <flags> -dM -E - </dev/null | sort
|
||||
|
||||
#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
|
||||
# define C4_CPU_X86_64
|
||||
# define C4_WORDSIZE 8
|
||||
# define C4_BYTE_ORDER _C4EL
|
||||
|
||||
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
|
||||
# define C4_CPU_X86
|
||||
# define C4_WORDSIZE 4
|
||||
# define C4_BYTE_ORDER _C4EL
|
||||
|
||||
#elif defined(__arm__) || defined(_M_ARM) \
|
||||
|| defined(__TARGET_ARCH_ARM) || defined(__aarch64__) || defined(_M_ARM64)
|
||||
# if defined(__aarch64__) || defined(_M_ARM64)
|
||||
# define C4_CPU_ARM64
|
||||
# define C4_CPU_ARMV8
|
||||
# define C4_WORDSIZE 8
|
||||
# else
|
||||
# define C4_CPU_ARM
|
||||
# define C4_WORDSIZE 4
|
||||
# if defined(__ARM_ARCH_8__) || defined(__ARM_ARCH_8A__) \
|
||||
|| (defined(__ARCH_ARM) && __ARCH_ARM >= 8) \
|
||||
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM >= 8)
|
||||
# define C4_CPU_ARMV8
|
||||
# elif defined(__ARM_ARCH_7__) || defined(_ARM_ARCH_7) \
|
||||
|| defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) \
|
||||
|| defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) \
|
||||
|| defined(__ARM_ARCH_7EM__) \
|
||||
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM >= 7) \
|
||||
|| (defined(_M_ARM) && _M_ARM >= 7)
|
||||
# define C4_CPU_ARMV7
|
||||
# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
|
||||
|| defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) \
|
||||
|| defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) \
|
||||
|| defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_6KZ__) \
|
||||
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM >= 6)
|
||||
# define C4_CPU_ARMV6
|
||||
# elif (defined(__ARM_ARCH) && __ARM_ARCH == 5) \
|
||||
|| defined(__ARM_ARCH_5TEJ__) \
|
||||
|| defined(__ARM_ARCH_5TE__) \
|
||||
|| defined(__ARM_ARCH_5T__) \
|
||||
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM >= 5)
|
||||
# define C4_CPU_ARMV5
|
||||
# elif (defined(__ARM_ARCH) && __ARM_ARCH == 4) \
|
||||
|| defined(__ARM_ARCH_4T__) \
|
||||
|| defined(__ARM_ARCH_4__) \
|
||||
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM >= 4)
|
||||
# define C4_CPU_ARMV4
|
||||
# else
|
||||
# error "unknown CPU architecture: ARM"
|
||||
# endif
|
||||
# endif
|
||||
# if defined(__ARMEL__) || defined(__LITTLE_ENDIAN__) || defined(__AARCH64EL__) \
|
||||
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) \
|
||||
|| defined(_MSC_VER) // winarm64 does not provide any of the above macros,
|
||||
// but advises little-endianess:
|
||||
// https://docs.microsoft.com/en-us/cpp/build/overview-of-arm-abi-conventions?view=msvc-170
|
||||
// So if it is visual studio compiling, we'll assume little endian.
|
||||
# define C4_BYTE_ORDER _C4EL
|
||||
# elif defined(__ARMEB__) || defined(__BIG_ENDIAN__) || defined(__AARCH64EB__) \
|
||||
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||||
# define C4_BYTE_ORDER _C4EB
|
||||
# elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_PDP_ENDIAN__)
|
||||
# define C4_BYTE_ORDER _C4EM
|
||||
# else
|
||||
# error "unknown endianness"
|
||||
# endif
|
||||
|
||||
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
|
||||
# define C4_CPU_IA64
|
||||
# define C4_WORDSIZE 8
|
||||
# define C4_BYTE_ORDER _C4EM
|
||||
// itanium is bi-endian - check byte order below
|
||||
|
||||
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \
|
||||
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \
|
||||
|| defined(_M_MPPC) || defined(_M_PPC)
|
||||
# if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
|
||||
# define C4_CPU_PPC64
|
||||
# define C4_WORDSIZE 8
|
||||
# else
|
||||
# define C4_CPU_PPC
|
||||
# define C4_WORDSIZE 4
|
||||
# endif
|
||||
# define C4_BYTE_ORDER _C4EM
|
||||
// ppc is bi-endian - check byte order below
|
||||
|
||||
#elif defined(__s390x__) || defined(__zarch__) || defined(__SYSC_ZARCH_)
|
||||
# define C4_CPU_S390_X
|
||||
# define C4_WORDSIZE 8
|
||||
# define C4_BYTE_ORDER _C4EB
|
||||
|
||||
#elif defined(__xtensa__) || defined(__XTENSA__)
|
||||
# define C4_CPU_XTENSA
|
||||
# define C4_WORDSIZE 4
|
||||
// not sure about this...
|
||||
# if defined(__XTENSA_EL__) || defined(__xtensa_el__)
|
||||
# define C4_BYTE_ORDER _C4EL
|
||||
# else
|
||||
# define C4_BYTE_ORDER _C4EB
|
||||
# endif
|
||||
|
||||
#elif defined(__riscv)
|
||||
# if __riscv_xlen == 64
|
||||
# define C4_CPU_RISCV64
|
||||
# define C4_WORDSIZE 8
|
||||
# else
|
||||
# define C4_CPU_RISCV32
|
||||
# define C4_WORDSIZE 4
|
||||
# endif
|
||||
# define C4_BYTE_ORDER _C4EL
|
||||
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
# define C4_BYTE_ORDER _C4EL
|
||||
# define C4_WORDSIZE 4
|
||||
|
||||
#elif defined(__loongarch__)
|
||||
# if defined(__loongarch64)
|
||||
# define C4_CPU_LOONGARCH64
|
||||
# define C4_WORDSIZE 8
|
||||
# else
|
||||
# define C4_CPU_LOONGARCH
|
||||
# define C4_WORDSIZE 4
|
||||
# endif
|
||||
# define C4_BYTE_ORDER _C4EL
|
||||
|
||||
#elif defined(__mips__) || defined(_mips) || defined(mips)
|
||||
# if defined(__mips)
|
||||
# if __mips == 64
|
||||
# define C4_CPU_MIPS64
|
||||
# define C4_WORDSIZE 8
|
||||
# elif __mips == 32
|
||||
# define C4_CPU_MIPS32
|
||||
# define C4_WORDSIZE 4
|
||||
# endif
|
||||
# elif defined(__arch64__) || (defined(__SIZE_WIDTH__) && __SIZE_WIDTH__ == 64) || (defined(__LP64__) && __LP64__)
|
||||
# define C4_CPU_MIPS64
|
||||
# define C4_WORDSIZE 8
|
||||
# elif defined(__arch32__) || (defined(__SIZE_WIDTH__) && __SIZE_WIDTH__ == 32) || (defined(__LP32__) && __LP32__)
|
||||
# define C4_CPU_MIPS32
|
||||
# define C4_WORDSIZE 4
|
||||
# else
|
||||
# error "unknown mips architecture"
|
||||
# endif
|
||||
# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define C4_BYTE_ORDER _C4EB
|
||||
# elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define C4_BYTE_ORDER _C4EL
|
||||
# else
|
||||
# error "unknown mips endianness"
|
||||
# endif
|
||||
|
||||
#elif defined(__sparc__) || defined(__sparc) || defined(sparc)
|
||||
# if defined(__arch64__) || (defined(__SIZE_WIDTH__) && __SIZE_WIDTH__ == 64) || (defined(__LP64__) && __LP64__)
|
||||
# define C4_CPU_SPARC64
|
||||
# define C4_WORDSIZE 8
|
||||
# elif defined(__arch32__) || (defined(__SIZE_WIDTH__) && __SIZE_WIDTH__ == 32) || (defined(__LP32__) && __LP32__)
|
||||
# define C4_CPU_SPARC32
|
||||
# define C4_WORDSIZE 4
|
||||
# else
|
||||
# error "unknown sparc architecture"
|
||||
# endif
|
||||
# define C4_BYTE_ORDER _C4EB
|
||||
|
||||
#elif defined(SWIG)
|
||||
# error "please define CPU architecture macros when compiling with swig"
|
||||
|
||||
#else
|
||||
# error "unknown CPU architecture"
|
||||
#endif
|
||||
|
||||
#define C4_LITTLE_ENDIAN (C4_BYTE_ORDER == _C4EL)
|
||||
#define C4_BIG_ENDIAN (C4_BYTE_ORDER == _C4EB)
|
||||
#define C4_MIXED_ENDIAN (C4_BYTE_ORDER == _C4EM)
|
||||
|
||||
#endif /* _C4_CPU_HPP_ */
|
||||
-798
@@ -1,798 +0,0 @@
|
||||
#ifndef C4_DUMP_HPP_
|
||||
#define C4_DUMP_HPP_
|
||||
|
||||
#include <c4/substr.hpp>
|
||||
|
||||
/** @file dump.hpp This file provides functions to dump several
|
||||
* arguments as strings to a user-provided function sink, for example
|
||||
* to implement a type-safe printf()-like function (where the sink
|
||||
* would just be a plain call to putchars()). The function sink can be
|
||||
* passed either by dynamic dispatching or by static dispatching (as a
|
||||
* template argument). There are analogs to @ref c4::cat() (@ref
|
||||
* c4::cat_dump() and @ref c4::cat_dump_resume()), @ref c4::catsep()
|
||||
* (@ref catsetp_dump() and @ref catsep_dump_resume()) and @ref
|
||||
* c4::format() (@ref c4::format_dump() and @ref
|
||||
* c4::format_dump_resume()). The analogs have two types: immediate
|
||||
* and resuming. An analog of immediate type cannot be retried when
|
||||
* the work buffer is too small; this means that successful dumps in
|
||||
* the first (successful) arguments will be dumped again in the
|
||||
* subsequent attempt to call. An analog of resuming type will only
|
||||
* ever dump as-yet-undumped arguments, through the use of @ref
|
||||
* DumpResults return type. */
|
||||
|
||||
namespace c4 {
|
||||
|
||||
C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wold-style-cast")
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** @defgroup dump_building_blocks Basic building blocks for dumping.
|
||||
*
|
||||
* The basic building block: given an argument and a
|
||||
* buffer, serialize the argument to the buffer using @ref
|
||||
* c4::to_chars(), and dump the buffer to the provided sink
|
||||
* function. When the argument is a string, no serialization is
|
||||
* performed, and the argument is dumped directly to the sink.
|
||||
*
|
||||
* @{ */
|
||||
|
||||
|
||||
/** Type of the function to be used as the sink. This function
|
||||
* receives as its argument the string with characters to send to the
|
||||
* sink.
|
||||
*
|
||||
* @warning the string passed to the sink may have zero length. If the
|
||||
* user sink uses memcpy(), the call to memcpy() should be defended
|
||||
* with a check for zero length (calling memcpy with zero length is
|
||||
* undefined behavior).
|
||||
* */
|
||||
using SinkPfn = void (*)(csubstr str);
|
||||
|
||||
|
||||
/** a traits class to use in SFINAE with @ref c4::dump() to select if
|
||||
* a type is treated as string type (which is dumped directly to the
|
||||
* sink, using to_csubstr()), or if the type is treated as a value,
|
||||
* which is first serialized to a buffer using to_chars(), and then
|
||||
* the serialization serialized as */
|
||||
template<class T> struct dump_directly : public std::false_type {};
|
||||
template<> struct dump_directly<csubstr> : public std::true_type {};
|
||||
template<> struct dump_directly< substr> : public std::true_type {};
|
||||
template<> struct dump_directly<const char*> : public std::true_type {};
|
||||
template<> struct dump_directly< char*> : public std::true_type {};
|
||||
template<size_t N> struct dump_directly<const char (&)[N]> : public std::true_type {};
|
||||
template<size_t N> struct dump_directly< char (&)[N]> : public std::true_type {};
|
||||
template<size_t N> struct dump_directly<const char[N]> : public std::true_type {};
|
||||
template<size_t N> struct dump_directly< char[N]> : public std::true_type {};
|
||||
|
||||
|
||||
/** Dump a string-type object to the (statically dispatched) sink. The
|
||||
* string is dumped directly, without any intermediate serialization.
|
||||
*
|
||||
* @return the number of bytes needed to serialize the string-type
|
||||
* object, which is always 0 because there is no serialization
|
||||
*
|
||||
* @note the argument is considered a value when @ref
|
||||
* dump_directly<Arg> is a false type, which is the default. To enable
|
||||
* the argument to be treated as a string type, which is dumped
|
||||
* directly to the sink without intermediate serialization, define
|
||||
* dump_directly<T> to a true type.
|
||||
*
|
||||
* @warning the string passed to the sink may have zero length. If the
|
||||
* user sink uses memcpy(), the call to memcpy() should be defended
|
||||
* with a check for zero length (calling memcpy with zero length is
|
||||
* undefined behavior).
|
||||
*
|
||||
* @see dump_directly<T>
|
||||
*/
|
||||
template<SinkPfn sinkfn, class Arg>
|
||||
inline auto dump(substr buf, Arg const& a)
|
||||
-> typename std::enable_if<dump_directly<Arg>::value, size_t>::type
|
||||
{
|
||||
C4_ASSERT(!buf.overlaps(a));
|
||||
C4_UNUSED(buf);
|
||||
// dump directly, no need to serialize to the buffer
|
||||
sinkfn(to_csubstr(a));
|
||||
return 0; // no space was used in the buffer
|
||||
}
|
||||
/** Dump a string-type object to the (dynamically dispatched)
|
||||
* sink. The string is dumped directly, without any intermediate
|
||||
* serialization to the buffer.
|
||||
*
|
||||
* @return the number of bytes needed to serialize the string-type
|
||||
* object, which is always 0 because there is no serialization
|
||||
*
|
||||
* @note the argument is considered a value when @ref
|
||||
* dump_directly<Arg> is a false type, which is the default. To enable
|
||||
* the argument to be treated as a string type, which is dumped
|
||||
* directly to the sink without intermediate serialization, define
|
||||
* dump_directly<T> to a true type.
|
||||
*
|
||||
* @warning the string passed to the sink may have zero length. If the
|
||||
* user sink uses memcpy(), the call to memcpy() should be defended
|
||||
* with a check for zero length (calling memcpy with zero length is
|
||||
* undefined behavior).
|
||||
*
|
||||
* @see dump_directly<T>
|
||||
* */
|
||||
template<class SinkFn, class Arg>
|
||||
inline auto dump(SinkFn &&sinkfn, substr buf, Arg const& a)
|
||||
-> typename std::enable_if<dump_directly<Arg>::value, size_t>::type
|
||||
{
|
||||
C4_UNUSED(buf);
|
||||
C4_ASSERT(!buf.overlaps(a));
|
||||
// dump directly, no need to serialize to the buffer
|
||||
std::forward<SinkFn>(sinkfn)(to_csubstr(a));
|
||||
return 0; // no space was used in the buffer
|
||||
}
|
||||
|
||||
|
||||
/** Dump a value to the sink. Given an argument @p a and a buffer @p
|
||||
* buf, serialize the argument to the buffer using @ref to_chars(),
|
||||
* and then dump the buffer to the (statically dispatched) sink
|
||||
* function passed as the template argument. If the buffer is too
|
||||
* small to serialize the argument, the sink function is not called.
|
||||
*
|
||||
* @note the argument is considered a value when @ref
|
||||
* dump_directly<Arg> is a false type, which is the default. To enable
|
||||
* the argument to be treated as a string type, which is dumped
|
||||
* directly to the sink without intermediate serialization, define
|
||||
* dump_directly<T> to a true type.
|
||||
*
|
||||
* @see dump_directly<T>
|
||||
*
|
||||
* @return the number of characters required to serialize the
|
||||
* argument. */
|
||||
template<SinkPfn sinkfn, class Arg>
|
||||
inline auto dump(substr buf, Arg const& a)
|
||||
-> typename std::enable_if<!dump_directly<Arg>::value, size_t>::type
|
||||
{
|
||||
// serialize to the buffer
|
||||
const size_t sz = to_chars(buf, a);
|
||||
// dump the buffer to the sink
|
||||
if(C4_LIKELY(sz <= buf.len))
|
||||
{
|
||||
// NOTE: don't do this:
|
||||
//sinkfn(buf.first(sz));
|
||||
// ... but do this instead:
|
||||
sinkfn({buf.str, sz});
|
||||
// ... this is needed because Release builds for armv5 and
|
||||
// armv6 were failing for the first call, with the wrong
|
||||
// buffer being passed into the function (!)
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
/** Dump a value to the sink. Given an argument @p a and a buffer @p
|
||||
* buf, serialize the argument to the buffer using @ref
|
||||
* c4::to_chars(), and then dump the buffer to the (dynamically
|
||||
* dispatched) sink function, passed as @p sinkfn. If the buffer is too
|
||||
* small to serialize the argument, the sink function is not called.
|
||||
*
|
||||
* @note the argument is considered a value when @ref
|
||||
* dump_directly<Arg> is a false type, which is the default. To enable
|
||||
* the argument to be treated as a string type, which is dumped
|
||||
* directly to the sink without intermediate serialization, define
|
||||
* dump_directly<T> to a true type.
|
||||
*
|
||||
* @see @ref dump_directly<T>
|
||||
*
|
||||
* @return the number of characters required to serialize the
|
||||
* argument. */
|
||||
template<class SinkFn, class Arg>
|
||||
inline auto dump(SinkFn &&sinkfn, substr buf, Arg const& a)
|
||||
-> typename std::enable_if<!dump_directly<Arg>::value, size_t>::type
|
||||
{
|
||||
// serialize to the buffer
|
||||
const size_t sz = to_chars(buf, a);
|
||||
// dump the buffer to the sink
|
||||
if(C4_LIKELY(sz <= buf.len))
|
||||
{
|
||||
// NOTE: don't do this:
|
||||
//std::forward<SinkFn>(sinkfn)(buf.first(sz));
|
||||
// ... but do this instead:
|
||||
std::forward<SinkFn>(sinkfn)({buf.str, sz});
|
||||
// ... this is needed because Release builds for armv5 and
|
||||
// armv6 were failing for the first call, with the wrong
|
||||
// buffer being passed into the function (!)
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
/** An opaque type used by resumeable dump functions like @ref
|
||||
* cat_dump_resume(), @ref catsep_dump_resume() or @ref
|
||||
* format_dump_resume(). */
|
||||
struct DumpResults
|
||||
{
|
||||
enum : size_t { noarg = (size_t)-1 };
|
||||
size_t bufsize = 0;
|
||||
size_t lastok = noarg;
|
||||
bool success_until(size_t expected) const { return lastok == noarg ? false : lastok >= expected; }
|
||||
bool write_arg(size_t arg) const { return lastok == noarg || arg > lastok; }
|
||||
size_t argfail() const { return lastok + 1; }
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
/** @defgroup cat_dump Dump several arguments to a sink,
|
||||
* concatenated. This is the analog to @ref c4::cat(), with the
|
||||
* significant difference that each argument is immediately sent to
|
||||
* the sink (resulting in multiple calls to the sink function, once
|
||||
* per argument), whereas equivalent usage of c4::cat() would first
|
||||
* serialize all the arguments to the buffer, and then call the sink
|
||||
* once at the end. As a consequence, the size needed for the buffer
|
||||
* is only the maximum of the size needed for the arguments, whereas
|
||||
* with c4::cat(), the size needed for the buffer would be the sum of
|
||||
* the size needed for the arguments. When the size of dump
|
||||
*
|
||||
* @{ */
|
||||
|
||||
/// @cond dev
|
||||
// terminates the variadic recursion
|
||||
template<class SinkFn>
|
||||
size_t cat_dump(SinkFn &&, substr) // NOLINT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// terminates the variadic recursion
|
||||
template<SinkPfn sinkfn>
|
||||
size_t cat_dump(substr) // NOLINT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
||||
/** Dump several arguments to the (dynamically dispatched) sink
|
||||
* function, as if through c4::cat(). For each argument, @ref dump()
|
||||
* is called with the buffer and sink. If any of the arguments is too
|
||||
* large for the buffer, no subsequent argument is sent to the sink,
|
||||
* (but all the arguments are still processed to compute the size
|
||||
* required for the buffer). This function can be safely called with an
|
||||
* empty buffer.
|
||||
*
|
||||
* @return the size required for the buffer, which is the maximum size
|
||||
* across all arguments
|
||||
*
|
||||
* @note subsequent calls with the same set of arguments will dump
|
||||
* again the first successful arguments. If each argument must only be
|
||||
* sent once to the sink (for example with printf-like behavior), use
|
||||
* instead @ref cat_dump_resume(). */
|
||||
template<class SinkFn, class Arg, class... Args>
|
||||
size_t cat_dump(SinkFn &&sinkfn, substr buf, Arg const& a, Args const& ...more)
|
||||
{
|
||||
const size_t size_for_a = dump(std::forward<SinkFn>(sinkfn), buf, a);
|
||||
if(C4_UNLIKELY(size_for_a > buf.len))
|
||||
buf.len = 0; // ensure no more calls to the sink
|
||||
const size_t size_for_more = cat_dump(std::forward<SinkFn>(sinkfn), buf, more...);
|
||||
return size_for_more > size_for_a ? size_for_more : size_for_a;
|
||||
}
|
||||
|
||||
|
||||
/** Dump several arguments to the (statically dispatched) sink
|
||||
* function, as if through c4::cat(). For each argument, @ref dump()
|
||||
* is called with the buffer and sink. If any of the arguments is too
|
||||
* large for the buffer, no subsequent argument is sent to the sink,
|
||||
* (but all the arguments are still processed to compute the size
|
||||
* required for the buffer). This function can be safely called with an
|
||||
* empty buffer.
|
||||
*
|
||||
* @return the size required for the buffer, which is the maximum size
|
||||
* across all arguments
|
||||
*
|
||||
* @note subsequent calls with the same set of arguments will dump
|
||||
* again the first successful arguments. If each argument must only be
|
||||
* sent once to the sink (for example with printf-like behavior), use
|
||||
* instead @ref cat_dump_resume(). */
|
||||
template<SinkPfn sinkfn, class Arg, class... Args>
|
||||
size_t cat_dump(substr buf, Arg const& a, Args const& ...more)
|
||||
{
|
||||
const size_t size_for_a = dump<sinkfn>(buf, a);
|
||||
if(C4_UNLIKELY(size_for_a > buf.len))
|
||||
buf.len = 0; // ensure no more calls to the sink
|
||||
const size_t size_for_more = cat_dump<sinkfn>(buf, more...);
|
||||
return size_for_more > size_for_a ? size_for_more : size_for_a;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// @cond dev
|
||||
namespace detail {
|
||||
|
||||
// terminates the variadic recursion
|
||||
template<SinkPfn sinkfn>
|
||||
C4_ALWAYS_INLINE DumpResults cat_dump_resume(size_t, DumpResults results, substr)
|
||||
{
|
||||
return results;
|
||||
}
|
||||
|
||||
// terminates the variadic recursion
|
||||
template<class SinkFn>
|
||||
C4_ALWAYS_INLINE DumpResults cat_dump_resume(size_t, SinkFn &&, DumpResults results, substr) // NOLINT
|
||||
{
|
||||
return results;
|
||||
}
|
||||
|
||||
template<SinkPfn sinkfn, class Arg, class... Args>
|
||||
DumpResults cat_dump_resume(size_t currarg, DumpResults results, substr buf, Arg const& C4_RESTRICT a, Args const& ...more)
|
||||
{
|
||||
if(C4_LIKELY(results.write_arg(currarg)))
|
||||
{
|
||||
size_t sz = dump<sinkfn>(buf, a); // yield to the specialized function
|
||||
if(currarg == results.lastok + 1 && sz <= buf.len)
|
||||
results.lastok = currarg;
|
||||
results.bufsize = sz > results.bufsize ? sz : results.bufsize;
|
||||
}
|
||||
return detail::cat_dump_resume<sinkfn>(currarg + 1u, results, buf, more...);
|
||||
}
|
||||
|
||||
template<class SinkFn, class Arg, class... Args>
|
||||
DumpResults cat_dump_resume(size_t currarg, SinkFn &&sinkfn, DumpResults results, substr buf, Arg const& C4_RESTRICT a, Args const& ...more)
|
||||
{
|
||||
if(C4_LIKELY(results.write_arg(currarg)))
|
||||
{
|
||||
size_t sz = dump(std::forward<SinkFn>(sinkfn), buf, a); // yield to the specialized function
|
||||
if(currarg == results.lastok + 1 && sz <= buf.len)
|
||||
results.lastok = currarg;
|
||||
results.bufsize = sz > results.bufsize ? sz : results.bufsize;
|
||||
}
|
||||
return detail::cat_dump_resume(currarg + 1u, std::forward<SinkFn>(sinkfn), results, buf, more...);
|
||||
}
|
||||
} // namespace detail
|
||||
/// @endcond
|
||||
|
||||
|
||||
template<SinkPfn sinkfn, class Arg, class... Args>
|
||||
C4_ALWAYS_INLINE DumpResults cat_dump_resume(substr buf, Arg const& C4_RESTRICT a, Args const& ...more)
|
||||
{
|
||||
return detail::cat_dump_resume<sinkfn>(0u, DumpResults{}, buf, a, more...);
|
||||
}
|
||||
|
||||
template<class SinkFn, class Arg, class... Args>
|
||||
C4_ALWAYS_INLINE DumpResults cat_dump_resume(SinkFn &&sinkfn, substr buf, Arg const& C4_RESTRICT a, Args const& ...more)
|
||||
{
|
||||
return detail::cat_dump_resume(0u, std::forward<SinkFn>(sinkfn), DumpResults{}, buf, a, more...);
|
||||
}
|
||||
|
||||
|
||||
template<SinkPfn sinkfn, class Arg, class... Args>
|
||||
C4_ALWAYS_INLINE DumpResults cat_dump_resume(DumpResults results, substr buf, Arg const& C4_RESTRICT a, Args const& ...more)
|
||||
{
|
||||
if(results.bufsize > buf.len)
|
||||
return results;
|
||||
return detail::cat_dump_resume<sinkfn>(0u, results, buf, a, more...);
|
||||
}
|
||||
|
||||
template<class SinkFn, class Arg, class... Args>
|
||||
C4_ALWAYS_INLINE DumpResults cat_dump_resume(SinkFn &&sinkfn, DumpResults results, substr buf, Arg const& C4_RESTRICT a, Args const& ...more)
|
||||
{
|
||||
if(results.bufsize > buf.len)
|
||||
return results;
|
||||
return detail::cat_dump_resume(0u, std::forward<SinkFn>(sinkfn), results, buf, a, more...);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// @cond dev
|
||||
// terminate the recursion
|
||||
template<class SinkFn, class Sep>
|
||||
size_t catsep_dump(SinkFn &&, substr, Sep const& C4_RESTRICT) // NOLINT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// terminate the recursion
|
||||
template<SinkPfn sinkfn, class Sep>
|
||||
size_t catsep_dump(substr, Sep const& C4_RESTRICT) // NOLINT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
/** take the function pointer as a function argument */
|
||||
template<class SinkFn, class Sep, class Arg, class... Args>
|
||||
size_t catsep_dump(SinkFn &&sinkfn, substr buf, Sep const& sep, Arg const& a, Args const& ...more)
|
||||
{
|
||||
size_t sz = dump(std::forward<SinkFn>(sinkfn), buf, a);
|
||||
if(C4_UNLIKELY(sz > buf.len))
|
||||
buf.len = 0; // ensure no more calls
|
||||
if C4_IF_CONSTEXPR (sizeof...(more) > 0)
|
||||
{
|
||||
size_t szsep = dump(std::forward<SinkFn>(sinkfn), buf, sep);
|
||||
if(C4_UNLIKELY(szsep > buf.len))
|
||||
buf.len = 0; // ensure no more calls
|
||||
sz = sz > szsep ? sz : szsep;
|
||||
}
|
||||
size_t size_for_more = catsep_dump(std::forward<SinkFn>(sinkfn), buf, sep, more...);
|
||||
return size_for_more > sz ? size_for_more : sz;
|
||||
}
|
||||
|
||||
/** take the function pointer as a template argument */
|
||||
template<SinkPfn sinkfn, class Sep, class Arg, class... Args>
|
||||
size_t catsep_dump(substr buf, Sep const& sep, Arg const& a, Args const& ...more)
|
||||
{
|
||||
size_t sz = dump<sinkfn>(buf, a);
|
||||
if(C4_UNLIKELY(sz > buf.len))
|
||||
buf.len = 0; // ensure no more calls
|
||||
if C4_IF_CONSTEXPR (sizeof...(more) > 0)
|
||||
{
|
||||
size_t szsep = dump<sinkfn>(buf, sep);
|
||||
if(C4_UNLIKELY(szsep > buf.len))
|
||||
buf.len = 0; // ensure no more calls
|
||||
sz = sz > szsep ? sz : szsep;
|
||||
}
|
||||
size_t size_for_more = catsep_dump<sinkfn>(buf, sep, more...);
|
||||
return size_for_more > sz ? size_for_more : sz;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// @cond dev
|
||||
namespace detail {
|
||||
template<SinkPfn sinkfn, class Arg>
|
||||
void catsep_dump_resume_(size_t currarg, DumpResults *C4_RESTRICT results, substr *buf, Arg const& a)
|
||||
{
|
||||
if(C4_LIKELY(results->write_arg(currarg)))
|
||||
{
|
||||
size_t sz = dump<sinkfn>(*buf, a);
|
||||
results->bufsize = sz > results->bufsize ? sz : results->bufsize;
|
||||
if(C4_LIKELY(sz <= buf->len))
|
||||
results->lastok = currarg;
|
||||
else
|
||||
buf->len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<class SinkFn, class Arg>
|
||||
void catsep_dump_resume_(size_t currarg, SinkFn &&sinkfn, DumpResults *C4_RESTRICT results, substr *C4_RESTRICT buf, Arg const& C4_RESTRICT a)
|
||||
{
|
||||
if(C4_LIKELY(results->write_arg(currarg)))
|
||||
{
|
||||
size_t sz = dump(std::forward<SinkFn>(sinkfn), *buf, a);
|
||||
results->bufsize = sz > results->bufsize ? sz : results->bufsize;
|
||||
if(C4_LIKELY(sz <= buf->len))
|
||||
results->lastok = currarg;
|
||||
else
|
||||
buf->len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<SinkPfn sinkfn, class Sep, class Arg>
|
||||
C4_ALWAYS_INLINE void catsep_dump_resume(size_t currarg, DumpResults *C4_RESTRICT results, substr *C4_RESTRICT buf, Sep const&, Arg const& a)
|
||||
{
|
||||
detail::catsep_dump_resume_<sinkfn>(currarg, results, buf, a);
|
||||
}
|
||||
|
||||
template<class SinkFn, class Sep, class Arg>
|
||||
C4_ALWAYS_INLINE void catsep_dump_resume(size_t currarg, SinkFn &&sinkfn, DumpResults *C4_RESTRICT results, substr *C4_RESTRICT buf, Sep const&, Arg const& a)
|
||||
{
|
||||
detail::catsep_dump_resume_(currarg, std::forward<SinkFn>(sinkfn), results, buf, a);
|
||||
}
|
||||
|
||||
template<SinkPfn sinkfn, class Sep, class Arg, class... Args>
|
||||
C4_ALWAYS_INLINE void catsep_dump_resume(size_t currarg, DumpResults *C4_RESTRICT results, substr *C4_RESTRICT buf, Sep const& sep, Arg const& a, Args const& ...more)
|
||||
{
|
||||
detail::catsep_dump_resume_<sinkfn>(currarg , results, buf, a);
|
||||
detail::catsep_dump_resume_<sinkfn>(currarg + 1u, results, buf, sep);
|
||||
detail::catsep_dump_resume <sinkfn>(currarg + 2u, results, buf, sep, more...);
|
||||
}
|
||||
|
||||
template<class SinkFn, class Sep, class Arg, class... Args>
|
||||
C4_ALWAYS_INLINE void catsep_dump_resume(size_t currarg, SinkFn &&sinkfn, DumpResults *C4_RESTRICT results, substr *C4_RESTRICT buf, Sep const& sep, Arg const& a, Args const& ...more)
|
||||
{
|
||||
detail::catsep_dump_resume_(currarg , std::forward<SinkFn>(sinkfn), results, buf, a);
|
||||
detail::catsep_dump_resume_(currarg + 1u, std::forward<SinkFn>(sinkfn), results, buf, sep);
|
||||
detail::catsep_dump_resume (currarg + 2u, std::forward<SinkFn>(sinkfn), results, buf, sep, more...);
|
||||
}
|
||||
} // namespace detail
|
||||
/// @endcond
|
||||
|
||||
|
||||
template<SinkPfn sinkfn, class Sep, class... Args>
|
||||
C4_ALWAYS_INLINE DumpResults catsep_dump_resume(substr buf, Sep const& sep, Args const& ...args)
|
||||
{
|
||||
DumpResults results;
|
||||
detail::catsep_dump_resume<sinkfn>(0u, &results, &buf, sep, args...);
|
||||
return results;
|
||||
}
|
||||
|
||||
template<class SinkFn, class Sep, class... Args>
|
||||
C4_ALWAYS_INLINE DumpResults catsep_dump_resume(SinkFn &&sinkfn, substr buf, Sep const& sep, Args const& ...args)
|
||||
{
|
||||
DumpResults results;
|
||||
detail::catsep_dump_resume(0u, std::forward<SinkFn>(sinkfn), &results, &buf, sep, args...);
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
template<SinkPfn sinkfn, class Sep, class... Args>
|
||||
C4_ALWAYS_INLINE DumpResults catsep_dump_resume(DumpResults results, substr buf, Sep const& sep, Args const& ...args)
|
||||
{
|
||||
detail::catsep_dump_resume<sinkfn>(0u, &results, &buf, sep, args...);
|
||||
return results;
|
||||
}
|
||||
|
||||
template<class SinkFn, class Sep, class... Args>
|
||||
C4_ALWAYS_INLINE DumpResults catsep_dump_resume(SinkFn &&sinkfn, DumpResults results, substr buf, Sep const& sep, Args const& ...args)
|
||||
{
|
||||
detail::catsep_dump_resume(0u, std::forward<SinkFn>(sinkfn), &results, &buf, sep, args...);
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// @cond dev
|
||||
namespace detail {
|
||||
// terminate the recursion
|
||||
C4_ALWAYS_INLINE size_t _format_dump_compute_size()
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
template<class T>
|
||||
C4_ALWAYS_INLINE auto _format_dump_compute_size(T const&)
|
||||
-> typename std::enable_if<dump_directly<T>::value, size_t>::type
|
||||
{
|
||||
return 0u; // no buffer needed
|
||||
}
|
||||
template<class T>
|
||||
C4_ALWAYS_INLINE auto _format_dump_compute_size(T const& v)
|
||||
-> typename std::enable_if<!dump_directly<T>::value, size_t>::type
|
||||
{
|
||||
return to_chars(substr{}, v);
|
||||
}
|
||||
template<class Arg, class... Args>
|
||||
size_t _format_dump_compute_size(Arg const& a, Args const& ...more)
|
||||
{
|
||||
const size_t sz = _format_dump_compute_size(a); // don't call to_chars() directly
|
||||
const size_t rest = _format_dump_compute_size(more...);
|
||||
return sz > rest ? sz : rest;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// terminate the recursion
|
||||
template<class SinkFn>
|
||||
C4_ALWAYS_INLINE size_t format_dump(SinkFn &&sinkfn, substr, csubstr fmt)
|
||||
{
|
||||
// we can dump without using buf, so no need to check it
|
||||
std::forward<SinkFn>(sinkfn)(fmt);
|
||||
return 0u;
|
||||
}
|
||||
// terminate the recursion
|
||||
/** take the function pointer as a template argument */
|
||||
template<SinkPfn sinkfn>
|
||||
C4_ALWAYS_INLINE size_t format_dump(substr, csubstr fmt)
|
||||
{
|
||||
// we can dump without using buf, so no need to check it
|
||||
sinkfn(fmt);
|
||||
return 0u;
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
||||
/** take the function pointer as a function argument */
|
||||
template<class SinkFn, class Arg, class... Args>
|
||||
C4_NO_INLINE size_t format_dump(SinkFn &&sinkfn, substr buf, csubstr fmt, Arg const& a, Args const& ...more)
|
||||
{
|
||||
// we can dump without using buf
|
||||
// but we'll only dump if the buffer is ok
|
||||
size_t pos = fmt.find("{}"); // @todo use _find_fmt()
|
||||
if(C4_UNLIKELY(pos == csubstr::npos))
|
||||
{
|
||||
std::forward<SinkFn>(sinkfn)(fmt);
|
||||
return 0u;
|
||||
}
|
||||
std::forward<SinkFn>(sinkfn)(fmt.first(pos)); // we can dump without using buf
|
||||
fmt = fmt.sub(pos + 2); // skip {} do this before assigning to pos again
|
||||
pos = dump(std::forward<SinkFn>(sinkfn), buf, a); // reuse pos to get needed_size
|
||||
// dump no more if the buffer was exhausted
|
||||
size_t size_for_more;
|
||||
if(C4_LIKELY(pos <= buf.len))
|
||||
size_for_more = format_dump(std::forward<SinkFn>(sinkfn), buf, fmt, more...);
|
||||
else
|
||||
size_for_more = detail::_format_dump_compute_size(more...);
|
||||
return size_for_more > pos ? size_for_more : pos;
|
||||
}
|
||||
|
||||
/** take the function pointer as a template argument */
|
||||
template<SinkPfn sinkfn, class Arg, class... Args>
|
||||
C4_NO_INLINE size_t format_dump(substr buf, csubstr fmt, Arg const& C4_RESTRICT a, Args const& ...more)
|
||||
{
|
||||
// we can dump without using buf
|
||||
// but we'll only dump if the buffer is ok
|
||||
size_t pos = fmt.find("{}"); // @todo use _find_fmt()
|
||||
if(C4_UNLIKELY(pos == csubstr::npos))
|
||||
{
|
||||
sinkfn(fmt);
|
||||
return 0u;
|
||||
}
|
||||
sinkfn(fmt.first(pos)); // we can dump without using buf
|
||||
fmt = fmt.sub(pos + 2); // skip {} do this before assigning to pos again
|
||||
pos = dump<sinkfn>(buf, a); // reuse pos to get needed_size
|
||||
// dump no more if the buffer was exhausted
|
||||
size_t size_for_more;
|
||||
if(C4_LIKELY(pos <= buf.len))
|
||||
size_for_more = format_dump<sinkfn>(buf, fmt, more...);
|
||||
else
|
||||
size_for_more = detail::_format_dump_compute_size(more...);
|
||||
return size_for_more > pos ? size_for_more : pos;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// @cond dev
|
||||
namespace detail {
|
||||
// terminate the recursion
|
||||
template<SinkPfn sinkfn>
|
||||
DumpResults format_dump_resume(size_t currarg, DumpResults results, substr, csubstr fmt)
|
||||
{
|
||||
if(C4_LIKELY(results.write_arg(currarg)))
|
||||
{
|
||||
// we can dump without using buf
|
||||
sinkfn(fmt);
|
||||
results.lastok = currarg;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
// terminate the recursion
|
||||
template<class SinkFn>
|
||||
DumpResults format_dump_resume(size_t currarg, SinkFn &&sinkfn, DumpResults results, substr, csubstr fmt)
|
||||
{
|
||||
if(C4_LIKELY(results.write_arg(currarg)))
|
||||
{
|
||||
// we can dump without using buf
|
||||
std::forward<SinkFn>(sinkfn)(fmt);
|
||||
results.lastok = currarg;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
template<SinkPfn sinkfn, class Arg, class... Args>
|
||||
DumpResults format_dump_resume(size_t currarg, DumpResults results, substr buf, csubstr fmt, Arg const& a, Args const& ...more)
|
||||
{
|
||||
// we need to process the format even if we're not
|
||||
// going to print the first arguments because we're resuming
|
||||
const size_t pos = fmt.find("{}"); // @todo use _find_fmt()
|
||||
if(C4_LIKELY(pos != csubstr::npos))
|
||||
{
|
||||
if(C4_LIKELY(results.write_arg(currarg)))
|
||||
{
|
||||
sinkfn(fmt.first(pos));
|
||||
results.lastok = currarg;
|
||||
}
|
||||
if(C4_LIKELY(results.write_arg(currarg + 1u)))
|
||||
{
|
||||
const size_t len = dump<sinkfn>(buf, a);
|
||||
results.bufsize = len > results.bufsize ? len : results.bufsize;
|
||||
if(C4_LIKELY(len <= buf.len))
|
||||
{
|
||||
results.lastok = currarg + 1u;
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t rest = _format_dump_compute_size(more...);
|
||||
results.bufsize = rest > results.bufsize ? rest : results.bufsize;
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(C4_LIKELY(results.write_arg(currarg)))
|
||||
{
|
||||
sinkfn(fmt);
|
||||
results.lastok = currarg;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
// NOTE: sparc64 had trouble with reassignment to fmt, and
|
||||
// was passing the original fmt to the recursion:
|
||||
//fmt = fmt.sub(pos + 2); // DONT!
|
||||
return detail::format_dump_resume<sinkfn>(currarg + 2u, results, buf, fmt.sub(pos + 2), more...);
|
||||
}
|
||||
|
||||
|
||||
template<class SinkFn, class Arg, class... Args>
|
||||
DumpResults format_dump_resume(size_t currarg, SinkFn &&sinkfn, DumpResults results, substr buf, csubstr fmt, Arg const& a, Args const& ...more)
|
||||
{
|
||||
// we need to process the format even if we're not
|
||||
// going to print the first arguments because we're resuming
|
||||
const size_t pos = fmt.find("{}"); // @todo use _find_fmt()
|
||||
if(C4_LIKELY(pos != csubstr::npos))
|
||||
{
|
||||
if(C4_LIKELY(results.write_arg(currarg)))
|
||||
{
|
||||
std::forward<SinkFn>(sinkfn)(fmt.first(pos));
|
||||
results.lastok = currarg;
|
||||
}
|
||||
if(C4_LIKELY(results.write_arg(currarg + 1u)))
|
||||
{
|
||||
const size_t len = dump(std::forward<SinkFn>(sinkfn), buf, a);
|
||||
results.bufsize = len > results.bufsize ? len : results.bufsize;
|
||||
if(C4_LIKELY(len <= buf.len))
|
||||
{
|
||||
results.lastok = currarg + 1u;
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t rest = _format_dump_compute_size(more...);
|
||||
results.bufsize = rest > results.bufsize ? rest : results.bufsize;
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(C4_LIKELY(results.write_arg(currarg)))
|
||||
{
|
||||
std::forward<SinkFn>(sinkfn)(fmt);
|
||||
results.lastok = currarg;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
// NOTE: sparc64 had trouble with reassignment to fmt, and
|
||||
// was passing the original fmt to the recursion:
|
||||
//fmt = fmt.sub(pos + 2); // DONT!
|
||||
return detail::format_dump_resume(currarg + 2u, std::forward<SinkFn>(sinkfn), results, buf, fmt.sub(pos + 2), more...);
|
||||
}
|
||||
} // namespace detail
|
||||
/// @endcond
|
||||
|
||||
|
||||
template<SinkPfn sinkfn, class... Args>
|
||||
C4_ALWAYS_INLINE DumpResults format_dump_resume(substr buf, csubstr fmt, Args const& ...args)
|
||||
{
|
||||
return detail::format_dump_resume<sinkfn>(0u, DumpResults{}, buf, fmt, args...);
|
||||
}
|
||||
|
||||
template<class SinkFn, class... Args>
|
||||
C4_ALWAYS_INLINE DumpResults format_dump_resume(SinkFn &&sinkfn, substr buf, csubstr fmt, Args const& ...args)
|
||||
{
|
||||
return detail::format_dump_resume(0u, std::forward<SinkFn>(sinkfn), DumpResults{}, buf, fmt, args...);
|
||||
}
|
||||
|
||||
|
||||
template<SinkPfn sinkfn, class... Args>
|
||||
C4_ALWAYS_INLINE DumpResults format_dump_resume(DumpResults results, substr buf, csubstr fmt, Args const& ...args)
|
||||
{
|
||||
return detail::format_dump_resume<sinkfn>(0u, results, buf, fmt, args...);
|
||||
}
|
||||
|
||||
template<class SinkFn, class... Args>
|
||||
C4_ALWAYS_INLINE DumpResults format_dump_resume(SinkFn &&sinkfn, DumpResults results, substr buf, csubstr fmt, Args const& ...args)
|
||||
{
|
||||
return detail::format_dump_resume(0u, std::forward<SinkFn>(sinkfn), results, buf, fmt, args...);
|
||||
}
|
||||
|
||||
C4_SUPPRESS_WARNING_GCC_CLANG_POP
|
||||
|
||||
} // namespace c4
|
||||
|
||||
|
||||
#endif /* C4_DUMP_HPP_ */
|
||||
-440
@@ -1,440 +0,0 @@
|
||||
#ifndef _C4_ERROR_HPP_
|
||||
#define _C4_ERROR_HPP_
|
||||
|
||||
/** @file error.hpp Facilities for error reporting and runtime assertions. */
|
||||
|
||||
/** @defgroup error_checking Error checking */
|
||||
|
||||
#include "c4/config.hpp"
|
||||
|
||||
#ifdef _DOXYGEN_
|
||||
/** if this is defined and exceptions are enabled, then calls to C4_ERROR()
|
||||
* will throw an exception
|
||||
* @ingroup error_checking */
|
||||
# define C4_EXCEPTIONS_ENABLED
|
||||
/** if this is defined and exceptions are enabled, then calls to C4_ERROR()
|
||||
* will throw an exception
|
||||
* @see C4_EXCEPTIONS_ENABLED
|
||||
* @ingroup error_checking */
|
||||
# define C4_ERROR_THROWS_EXCEPTION
|
||||
/** evaluates to noexcept when C4_ERROR might be called and
|
||||
* exceptions are disabled. Otherwise, defaults to nothing.
|
||||
* @ingroup error_checking */
|
||||
# define C4_NOEXCEPT
|
||||
#endif // _DOXYGEN_
|
||||
|
||||
#if defined(C4_EXCEPTIONS_ENABLED) && defined(C4_ERROR_THROWS_EXCEPTION)
|
||||
# define C4_NOEXCEPT
|
||||
#else
|
||||
# define C4_NOEXCEPT noexcept
|
||||
#endif
|
||||
|
||||
|
||||
namespace c4 {
|
||||
namespace detail {
|
||||
struct fail_type__ {};
|
||||
} // detail
|
||||
} // c4
|
||||
#define C4_STATIC_ERROR(dummy_type, errmsg) \
|
||||
static_assert(std::is_same<dummy_type, c4::detail::fail_type__>::value, errmsg)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define C4_ASSERT_SAME_TYPE(ty1, ty2) \
|
||||
C4_STATIC_ASSERT(std::is_same<ty1 C4_COMMA_X ty2>::value)
|
||||
|
||||
#define C4_ASSERT_DIFF_TYPE(ty1, ty2) \
|
||||
C4_STATIC_ASSERT( ! std::is_same<ty1 C4_COMMA_X ty2>::value)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef _DOXYGEN_
|
||||
/** utility macro that triggers a breakpoint when
|
||||
* the debugger is attached and NDEBUG is not defined.
|
||||
* @ingroup error_checking */
|
||||
# define C4_DEBUG_BREAK()
|
||||
#endif // _DOXYGEN_
|
||||
|
||||
|
||||
#if defined(NDEBUG) || defined(C4_NO_DEBUG_BREAK)
|
||||
# define C4_DEBUG_BREAK()
|
||||
#else
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wundef"
|
||||
# if !defined(__APPLE_CC__)
|
||||
# if __clang_major__ >= 10
|
||||
# pragma clang diagnostic ignored "-Wgnu-inline-cpp-without-extern" // debugbreak/debugbreak.h:50:16: error: 'gnu_inline' attribute without 'extern' in C++ treated as externally available, this changed in Clang 10 [-Werror,-Wgnu-inline-cpp-without-extern]
|
||||
# endif
|
||||
# else
|
||||
# if __clang_major__ >= 13
|
||||
# pragma clang diagnostic ignored "-Wgnu-inline-cpp-without-extern" // debugbreak/debugbreak.h:50:16: error: 'gnu_inline' attribute without 'extern' in C++ treated as externally available, this changed in Clang 10 [-Werror,-Wgnu-inline-cpp-without-extern]
|
||||
# endif
|
||||
# endif
|
||||
# elif defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wundef"
|
||||
# endif
|
||||
# include <c4/ext/debugbreak/debugbreak.h>
|
||||
# define C4_DEBUG_BREAK() if(c4::is_debugger_attached()) { ::debug_break(); }
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# elif defined(__GNUC__)
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace c4 {
|
||||
C4CORE_EXPORT bool is_debugger_attached();
|
||||
} // namespace c4
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef __clang__
|
||||
/* NOTE: using , ## __VA_ARGS__ to deal with zero-args calls to
|
||||
* variadic macros is not portable, but works in clang, gcc, msvc, icc.
|
||||
* clang requires switching off compiler warnings for pedantic mode.
|
||||
* @see http://stackoverflow.com/questions/32047685/variadic-macro-without-arguments */
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" // warning: token pasting of ',' and __VA_ARGS__ is a GNU extension
|
||||
#elif defined(__GNUC__)
|
||||
/* GCC also issues a warning for zero-args calls to variadic macros.
|
||||
* This warning is switched on with -pedantic and apparently there is no
|
||||
* easy way to turn it off as with clang. But marking this as a system
|
||||
* header works.
|
||||
* @see https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html
|
||||
* @see http://stackoverflow.com/questions/35587137/ */
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace c4 {
|
||||
|
||||
typedef enum : uint32_t {
|
||||
/** when an error happens and the debugger is attached, call C4_DEBUG_BREAK().
|
||||
* Without effect otherwise. */
|
||||
ON_ERROR_DEBUGBREAK = 0x01u << 0u,
|
||||
/** when an error happens log a message. */
|
||||
ON_ERROR_LOG = 0x01u << 1u,
|
||||
/** when an error happens invoke a callback if it was set with
|
||||
* set_error_callback(). */
|
||||
ON_ERROR_CALLBACK = 0x01u << 2u,
|
||||
/** when an error happens call std::terminate(). */
|
||||
ON_ERROR_ABORT = 0x01u << 3u,
|
||||
/** when an error happens and exceptions are enabled throw an exception.
|
||||
* Without effect otherwise. */
|
||||
ON_ERROR_THROW = 0x01u << 4u,
|
||||
/** the default flags. */
|
||||
ON_ERROR_DEFAULTS = ON_ERROR_DEBUGBREAK|ON_ERROR_LOG|ON_ERROR_CALLBACK|ON_ERROR_ABORT
|
||||
} ErrorFlags_e;
|
||||
using error_flags = uint32_t;
|
||||
C4CORE_EXPORT void set_error_flags(error_flags f);
|
||||
C4CORE_EXPORT error_flags get_error_flags();
|
||||
|
||||
|
||||
using error_callback_type = void (*)(const char* msg, size_t msg_size);
|
||||
C4CORE_EXPORT void set_error_callback(error_callback_type cb);
|
||||
C4CORE_EXPORT error_callback_type get_error_callback();
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** RAII class controling the error settings inside a scope. */
|
||||
struct ScopedErrorSettings // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
|
||||
{
|
||||
error_flags m_flags;
|
||||
error_callback_type m_callback;
|
||||
|
||||
explicit ScopedErrorSettings(error_callback_type cb)
|
||||
: m_flags(get_error_flags()),
|
||||
m_callback(get_error_callback())
|
||||
{
|
||||
set_error_callback(cb);
|
||||
}
|
||||
explicit ScopedErrorSettings(error_flags flags)
|
||||
: m_flags(get_error_flags()),
|
||||
m_callback(get_error_callback())
|
||||
{
|
||||
set_error_flags(flags);
|
||||
}
|
||||
explicit ScopedErrorSettings(error_flags flags, error_callback_type cb)
|
||||
: m_flags(get_error_flags()),
|
||||
m_callback(get_error_callback())
|
||||
{
|
||||
set_error_flags(flags);
|
||||
set_error_callback(cb);
|
||||
}
|
||||
~ScopedErrorSettings()
|
||||
{
|
||||
set_error_flags(m_flags);
|
||||
set_error_callback(m_callback);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** source location */
|
||||
struct srcloc;
|
||||
|
||||
// watchout: for VS the [[noreturn]] needs to come before other annotations like C4CORE_EXPORT
|
||||
[[noreturn]] C4CORE_EXPORT void handle_error(srcloc s, const char *fmt, ...);
|
||||
C4CORE_EXPORT void handle_warning(srcloc s, const char *fmt, ...);
|
||||
|
||||
|
||||
# define C4_ERROR(msg, ...) \
|
||||
do { \
|
||||
if(c4::get_error_flags() & c4::ON_ERROR_DEBUGBREAK) \
|
||||
{ \
|
||||
C4_DEBUG_BREAK() \
|
||||
} \
|
||||
c4::handle_error(C4_SRCLOC(), msg, ## __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
|
||||
# define C4_WARNING(msg, ...) \
|
||||
c4::handle_warning(C4_SRCLOC(), msg, ## __VA_ARGS__)
|
||||
|
||||
|
||||
#if defined(C4_ERROR_SHOWS_FILELINE) && defined(C4_ERROR_SHOWS_FUNC)
|
||||
|
||||
struct srcloc
|
||||
{
|
||||
const char *file = "";
|
||||
const char *func = "";
|
||||
int line = 0;
|
||||
};
|
||||
#define C4_SRCLOC() c4::srcloc{__FILE__, C4_PRETTY_FUNC, __LINE__}
|
||||
|
||||
#elif defined(C4_ERROR_SHOWS_FILELINE)
|
||||
|
||||
struct srcloc
|
||||
{
|
||||
const char *file;
|
||||
int line;
|
||||
};
|
||||
#define C4_SRCLOC() c4::srcloc{__FILE__, __LINE__}
|
||||
|
||||
#elif ! defined(C4_ERROR_SHOWS_FUNC)
|
||||
|
||||
struct srcloc
|
||||
{
|
||||
};
|
||||
#define C4_SRCLOC() c4::srcloc()
|
||||
|
||||
#else
|
||||
# error not implemented
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// assertions
|
||||
|
||||
// Doxygen needs this so that only one definition counts
|
||||
#ifdef _DOXYGEN_
|
||||
/** Explicitly enables assertions, independently of NDEBUG status.
|
||||
* This is meant to allow enabling assertions even when NDEBUG is defined.
|
||||
* Defaults to undefined.
|
||||
* @ingroup error_checking */
|
||||
# define C4_USE_ASSERT
|
||||
/** assert that a condition is true; this is turned off when NDEBUG
|
||||
* is defined and C4_USE_ASSERT is not true.
|
||||
* @ingroup error_checking */
|
||||
# define C4_ASSERT
|
||||
/** same as C4_ASSERT(), additionally prints a printf-formatted message
|
||||
* @ingroup error_checking */
|
||||
# define C4_ASSERT_MSG
|
||||
/** evaluates to C4_NOEXCEPT when C4_XASSERT is disabled; otherwise, defaults
|
||||
* to noexcept
|
||||
* @ingroup error_checking */
|
||||
# define C4_NOEXCEPT_A
|
||||
#endif // _DOXYGEN_
|
||||
|
||||
#ifndef C4_USE_ASSERT
|
||||
# ifdef NDEBUG
|
||||
# define C4_USE_ASSERT 0
|
||||
# else
|
||||
# define C4_USE_ASSERT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if C4_USE_ASSERT
|
||||
# define C4_ASSERT(cond) C4_CHECK(cond)
|
||||
# define C4_ASSERT_MSG(cond, /*fmt, */...) C4_CHECK_MSG(cond, ## __VA_ARGS__)
|
||||
# define C4_ASSERT_IF(predicate, cond) if(predicate) { C4_ASSERT(cond); }
|
||||
# define C4_NOEXCEPT_A C4_NOEXCEPT
|
||||
#else
|
||||
# define C4_ASSERT(cond)
|
||||
# define C4_ASSERT_MSG(cond, /*fmt, */...)
|
||||
# define C4_ASSERT_IF(predicate, cond)
|
||||
# define C4_NOEXCEPT_A noexcept
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// extreme assertions
|
||||
|
||||
// Doxygen needs this so that only one definition counts
|
||||
#ifdef _DOXYGEN_
|
||||
/** Explicitly enables extreme assertions; this is meant to allow enabling
|
||||
* assertions even when NDEBUG is defined. Defaults to undefined.
|
||||
* @ingroup error_checking */
|
||||
# define C4_USE_XASSERT
|
||||
/** extreme assertion: can be switched off independently of
|
||||
* the regular assertion; use for example for bounds checking in hot code.
|
||||
* Turned on only when C4_USE_XASSERT is defined
|
||||
* @ingroup error_checking */
|
||||
# define C4_XASSERT
|
||||
/** same as C4_XASSERT(), and additionally prints a printf-formatted message
|
||||
* @ingroup error_checking */
|
||||
# define C4_XASSERT_MSG
|
||||
/** evaluates to C4_NOEXCEPT when C4_XASSERT is disabled; otherwise, defaults to noexcept
|
||||
* @ingroup error_checking */
|
||||
# define C4_NOEXCEPT_X
|
||||
#endif // _DOXYGEN_
|
||||
|
||||
#ifndef C4_USE_XASSERT
|
||||
# define C4_USE_XASSERT C4_USE_ASSERT
|
||||
#endif
|
||||
|
||||
#if C4_USE_XASSERT
|
||||
# define C4_XASSERT(cond) C4_CHECK(cond)
|
||||
# define C4_XASSERT_MSG(cond, /*fmt, */...) C4_CHECK_MSG(cond, ## __VA_ARGS__)
|
||||
# define C4_XASSERT_IF(predicate, cond) if(predicate) { C4_XASSERT(cond); }
|
||||
# define C4_NOEXCEPT_X C4_NOEXCEPT
|
||||
#else
|
||||
# define C4_XASSERT(cond)
|
||||
# define C4_XASSERT_MSG(cond, /*fmt, */...)
|
||||
# define C4_XASSERT_IF(predicate, cond)
|
||||
# define C4_NOEXCEPT_X noexcept
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// checks: never switched-off
|
||||
|
||||
/** Check that a condition is true, or raise an error when not
|
||||
* true. Unlike C4_ASSERT(), this check is not disabled in non-debug
|
||||
* builds.
|
||||
* @see C4_ASSERT
|
||||
* @ingroup error_checking
|
||||
*
|
||||
* @todo add constexpr-compatible compile-time assert:
|
||||
* https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/
|
||||
*/
|
||||
#define C4_CHECK(cond) \
|
||||
do { \
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
C4_ERROR("check failed: %s", #cond); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
/** like C4_CHECK(), and additionally log a printf-style message.
|
||||
* @see C4_CHECK
|
||||
* @ingroup error_checking */
|
||||
#define C4_CHECK_MSG(cond, fmt, ...) \
|
||||
do { \
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
C4_ERROR("check failed: " #cond "\n" fmt, ## __VA_ARGS__); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Common error conditions
|
||||
|
||||
#define C4_NOT_IMPLEMENTED() C4_ERROR("NOT IMPLEMENTED")
|
||||
#define C4_NOT_IMPLEMENTED_MSG(/*msg, */...) C4_ERROR("NOT IMPLEMENTED: " __VA_ARGS__)
|
||||
#define C4_NOT_IMPLEMENTED_IF(condition) do { if(C4_UNLIKELY(condition)) { C4_ERROR("NOT IMPLEMENTED"); } } while(0)
|
||||
#define C4_NOT_IMPLEMENTED_IF_MSG(condition, /*msg, */...) do { if(C4_UNLIKELY(condition)) { C4_ERROR("NOT IMPLEMENTED: " __VA_ARGS__); } } while(0)
|
||||
|
||||
#define C4_NEVER_REACH() do { C4_ERROR("never reach this point"); C4_UNREACHABLE(); } while(0)
|
||||
#define C4_NEVER_REACH_MSG(/*msg, */...) do { C4_ERROR("never reach this point: " __VA_ARGS__); C4_UNREACHABLE(); } while(0)
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// helpers for warning suppression
|
||||
// idea adapted from https://github.com/onqtam/doctest/
|
||||
|
||||
// TODO: add C4_MESSAGE() https://stackoverflow.com/questions/18252351/custom-preprocessor-macro-for-a-conditional-pragma-message-xxx?rq=1
|
||||
|
||||
|
||||
#ifdef C4_MSVC
|
||||
#define C4_SUPPRESS_WARNING_MSVC_PUSH __pragma(warning(push))
|
||||
#define C4_SUPPRESS_WARNING_MSVC(w) __pragma(warning(disable : w))
|
||||
#define C4_SUPPRESS_WARNING_MSVC_POP __pragma(warning(pop))
|
||||
#else // C4_MSVC
|
||||
#define C4_SUPPRESS_WARNING_MSVC_PUSH
|
||||
#define C4_SUPPRESS_WARNING_MSVC(w)
|
||||
#define C4_SUPPRESS_WARNING_MSVC_POP
|
||||
#endif // C4_MSVC
|
||||
|
||||
|
||||
#ifdef C4_CLANG
|
||||
#define C4_PRAGMA_TO_STR(x) _Pragma(#x)
|
||||
#define C4_SUPPRESS_WARNING_CLANG_PUSH _Pragma("clang diagnostic push")
|
||||
#define C4_SUPPRESS_WARNING_CLANG(w) C4_PRAGMA_TO_STR(clang diagnostic ignored w)
|
||||
#define C4_SUPPRESS_WARNING_CLANG_POP _Pragma("clang diagnostic pop")
|
||||
#else // C4_CLANG
|
||||
#define C4_SUPPRESS_WARNING_CLANG_PUSH
|
||||
#define C4_SUPPRESS_WARNING_CLANG(w)
|
||||
#define C4_SUPPRESS_WARNING_CLANG_POP
|
||||
#endif // C4_CLANG
|
||||
|
||||
|
||||
#ifdef C4_GCC
|
||||
#define C4_PRAGMA_TO_STR(x) _Pragma(#x)
|
||||
#define C4_SUPPRESS_WARNING_GCC_PUSH _Pragma("GCC diagnostic push")
|
||||
#define C4_SUPPRESS_WARNING_GCC(w) C4_PRAGMA_TO_STR(GCC diagnostic ignored w)
|
||||
#define C4_SUPPRESS_WARNING_GCC_POP _Pragma("GCC diagnostic pop")
|
||||
#else // C4_GCC
|
||||
#define C4_SUPPRESS_WARNING_GCC_PUSH
|
||||
#define C4_SUPPRESS_WARNING_GCC(w)
|
||||
#define C4_SUPPRESS_WARNING_GCC_POP
|
||||
#endif // C4_GCC
|
||||
|
||||
|
||||
#define C4_SUPPRESS_WARNING_MSVC_WITH_PUSH(w) \
|
||||
C4_SUPPRESS_WARNING_MSVC_PUSH \
|
||||
C4_SUPPRESS_WARNING_MSVC(w)
|
||||
|
||||
#define C4_SUPPRESS_WARNING_CLANG_WITH_PUSH(w) \
|
||||
C4_SUPPRESS_WARNING_CLANG_PUSH \
|
||||
C4_SUPPRESS_WARNING_CLANG(w)
|
||||
|
||||
#define C4_SUPPRESS_WARNING_GCC_WITH_PUSH(w) \
|
||||
C4_SUPPRESS_WARNING_GCC_PUSH \
|
||||
C4_SUPPRESS_WARNING_GCC(w)
|
||||
|
||||
|
||||
#define C4_SUPPRESS_WARNING_GCC_CLANG_PUSH \
|
||||
C4_SUPPRESS_WARNING_GCC_PUSH \
|
||||
C4_SUPPRESS_WARNING_CLANG_PUSH
|
||||
|
||||
#define C4_SUPPRESS_WARNING_GCC_CLANG(w) \
|
||||
C4_SUPPRESS_WARNING_GCC(w) \
|
||||
C4_SUPPRESS_WARNING_CLANG(w)
|
||||
|
||||
#define C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH(w) \
|
||||
C4_SUPPRESS_WARNING_GCC_WITH_PUSH(w) \
|
||||
C4_SUPPRESS_WARNING_CLANG_WITH_PUSH(w)
|
||||
|
||||
#define C4_SUPPRESS_WARNING_GCC_CLANG_POP \
|
||||
C4_SUPPRESS_WARNING_GCC_POP \
|
||||
C4_SUPPRESS_WARNING_CLANG_POP
|
||||
|
||||
} // namespace c4
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif /* _C4_ERROR_HPP_ */
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
#ifndef C4_EXPORT_HPP_
|
||||
#define C4_EXPORT_HPP_
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef C4CORE_SHARED
|
||||
#ifdef C4CORE_EXPORTS
|
||||
#define C4CORE_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define C4CORE_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define C4CORE_EXPORT
|
||||
#endif
|
||||
#else
|
||||
#define C4CORE_EXPORT
|
||||
#endif
|
||||
|
||||
#endif /* C4CORE_EXPORT_HPP_ */
|
||||
-1058
File diff suppressed because it is too large
Load Diff
-358
@@ -1,358 +0,0 @@
|
||||
#ifndef _C4_LANGUAGE_HPP_
|
||||
#define _C4_LANGUAGE_HPP_
|
||||
|
||||
/** @file language.hpp Provides language standard information macros and
|
||||
* compiler agnostic utility macros: namespace facilities, function attributes,
|
||||
* variable attributes, etc.
|
||||
* @ingroup basic_headers */
|
||||
|
||||
#include "c4/preprocessor.hpp"
|
||||
#include "c4/compiler.hpp"
|
||||
|
||||
/* Detect C++ standard.
|
||||
* @see http://stackoverflow.com/a/7132549/5875572 */
|
||||
#ifndef C4_CPP
|
||||
# if defined(_MSC_VER) && !defined(__clang__)
|
||||
# if _MSC_VER >= 1910 // >VS2015: VS2017, VS2019, VS2022
|
||||
# if (!defined(_MSVC_LANG))
|
||||
# error _MSVC not defined
|
||||
# endif
|
||||
# if _MSVC_LANG >= 201705L
|
||||
# define C4_CPP 20
|
||||
# define C4_CPP20
|
||||
# elif _MSVC_LANG == 201703L
|
||||
# define C4_CPP 17
|
||||
# define C4_CPP17
|
||||
# elif _MSVC_LANG >= 201402L
|
||||
# define C4_CPP 14
|
||||
# define C4_CPP14
|
||||
# elif _MSVC_LANG >= 201103L
|
||||
# define C4_CPP 11
|
||||
# define C4_CPP11
|
||||
# else
|
||||
# error C++ lesser than C++11 not supported
|
||||
# endif
|
||||
# else
|
||||
# if _MSC_VER == 1900
|
||||
# define C4_CPP 14 // VS2015 is c++14 https://devblogs.microsoft.com/cppblog/c111417-features-in-vs-2015-rtm/
|
||||
# define C4_CPP14
|
||||
# elif _MSC_VER == 1800 // VS2013
|
||||
# define C4_CPP 11
|
||||
# define C4_CPP11
|
||||
# else
|
||||
# error C++ lesser than C++11 not supported
|
||||
# endif
|
||||
# endif
|
||||
# elif defined(__INTEL_COMPILER) // https://software.intel.com/en-us/node/524490
|
||||
# ifdef __INTEL_CXX20_MODE__ // not sure about this
|
||||
# define C4_CPP 20
|
||||
# define C4_CPP20
|
||||
# elif defined __INTEL_CXX17_MODE__ // not sure about this
|
||||
# define C4_CPP 17
|
||||
# define C4_CPP17
|
||||
# elif defined __INTEL_CXX14_MODE__ // not sure about this
|
||||
# define C4_CPP 14
|
||||
# define C4_CPP14
|
||||
# elif defined __INTEL_CXX11_MODE__
|
||||
# define C4_CPP 11
|
||||
# define C4_CPP11
|
||||
# else
|
||||
# error C++ lesser than C++11 not supported
|
||||
# endif
|
||||
# else
|
||||
# ifndef __cplusplus
|
||||
# error __cplusplus is not defined?
|
||||
# endif
|
||||
# if __cplusplus == 1
|
||||
# error cannot handle __cplusplus==1
|
||||
# elif __cplusplus >= 201709L
|
||||
# define C4_CPP 20
|
||||
# define C4_CPP20
|
||||
# elif __cplusplus >= 201703L
|
||||
# define C4_CPP 17
|
||||
# define C4_CPP17
|
||||
# elif __cplusplus >= 201402L
|
||||
# define C4_CPP 14
|
||||
# define C4_CPP14
|
||||
# elif __cplusplus >= 201103L
|
||||
# define C4_CPP 11
|
||||
# define C4_CPP11
|
||||
# elif __cplusplus >= 199711L
|
||||
# error C++ lesser than C++11 not supported
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
# ifdef C4_CPP == 20
|
||||
# define C4_CPP20
|
||||
# elif C4_CPP == 17
|
||||
# define C4_CPP17
|
||||
# elif C4_CPP == 14
|
||||
# define C4_CPP14
|
||||
# elif C4_CPP == 11
|
||||
# define C4_CPP11
|
||||
# elif C4_CPP == 98
|
||||
# define C4_CPP98
|
||||
# error C++ lesser than C++11 not supported
|
||||
# else
|
||||
# error C4_CPP must be one of 20, 17, 14, 11, 98
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef C4_CPP20
|
||||
# define C4_CPP17
|
||||
# define C4_CPP14
|
||||
# define C4_CPP11
|
||||
#elif defined(C4_CPP17)
|
||||
# define C4_CPP14
|
||||
# define C4_CPP11
|
||||
#elif defined(C4_CPP14)
|
||||
# define C4_CPP11
|
||||
#endif
|
||||
|
||||
/** lifted from this answer: http://stackoverflow.com/a/20170989/5875572 */
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
# if _MSC_VER < 1900
|
||||
# define C4_CONSTEXPR11
|
||||
# define C4_CONSTEXPR14
|
||||
# elif _MSC_VER < 2000
|
||||
# define C4_CONSTEXPR11 constexpr
|
||||
# define C4_CONSTEXPR14
|
||||
# else
|
||||
# define C4_CONSTEXPR11 constexpr
|
||||
# define C4_CONSTEXPR14 constexpr
|
||||
# endif
|
||||
#else
|
||||
# if __cplusplus < 201103
|
||||
# define C4_CONSTEXPR11
|
||||
# define C4_CONSTEXPR14
|
||||
# elif __cplusplus == 201103
|
||||
# define C4_CONSTEXPR11 constexpr
|
||||
# define C4_CONSTEXPR14
|
||||
# else
|
||||
# define C4_CONSTEXPR11 constexpr
|
||||
# define C4_CONSTEXPR14 constexpr
|
||||
# endif
|
||||
#endif // _MSC_VER
|
||||
|
||||
|
||||
#if C4_CPP < 17
|
||||
#define C4_IF_CONSTEXPR
|
||||
#define C4_INLINE_CONSTEXPR constexpr
|
||||
#else
|
||||
#define C4_IF_CONSTEXPR constexpr
|
||||
#define C4_INLINE_CONSTEXPR inline constexpr
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
# if (defined(_CPPUNWIND) && (_CPPUNWIND == 1))
|
||||
# define C4_EXCEPTIONS
|
||||
# endif
|
||||
#else
|
||||
# if defined(__EXCEPTIONS) || defined(__cpp_exceptions)
|
||||
# define C4_EXCEPTIONS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef C4_EXCEPTIONS
|
||||
# define C4_IF_EXCEPTIONS_(exc_code, setjmp_code) exc_code
|
||||
# define C4_IF_EXCEPTIONS(exc_code, setjmp_code) do { exc_code } while(0)
|
||||
#else
|
||||
# define C4_IF_EXCEPTIONS_(exc_code, setjmp_code) setjmp_code
|
||||
# define C4_IF_EXCEPTIONS(exc_code, setjmp_code) do { setjmp_code } while(0)
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
# if defined(_CPPRTTI)
|
||||
# define C4_RTTI
|
||||
# endif
|
||||
#else
|
||||
# if defined(__GXX_RTTI)
|
||||
# define C4_RTTI
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef C4_RTTI
|
||||
# define C4_IF_RTTI_(code_rtti, code_no_rtti) code_rtti
|
||||
# define C4_IF_RTTI(code_rtti, code_no_rtti) do { code_rtti } while(0)
|
||||
#else
|
||||
# define C4_IF_RTTI_(code_rtti, code_no_rtti) code_no_rtti
|
||||
# define C4_IF_RTTI(code_rtti, code_no_rtti) do { code_no_rtti } while(0)
|
||||
#endif
|
||||
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
#define _C4_BEGIN_NAMESPACE(ns) namespace ns {
|
||||
#define _C4_END_NAMESPACE(ns) }
|
||||
|
||||
// MSVC cant handle the C4_FOR_EACH macro... need to fix this
|
||||
//#define C4_BEGIN_NAMESPACE(...) C4_FOR_EACH_SEP(_C4_BEGIN_NAMESPACE, , __VA_ARGS__)
|
||||
//#define C4_END_NAMESPACE(...) C4_FOR_EACH_SEP(_C4_END_NAMESPACE, , __VA_ARGS__)
|
||||
#define C4_BEGIN_NAMESPACE(ns) namespace ns {
|
||||
#define C4_END_NAMESPACE(ns) }
|
||||
|
||||
#define C4_BEGIN_HIDDEN_NAMESPACE namespace /*hidden*/ {
|
||||
#define C4_END_HIDDEN_NAMESPACE } /* namespace hidden */
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
#ifndef C4_API
|
||||
# if defined(_MSC_VER) && !defined(__clang__)
|
||||
# if defined(C4_EXPORT)
|
||||
# define C4_API __declspec(dllexport)
|
||||
# elif defined(C4_IMPORT)
|
||||
# define C4_API __declspec(dllimport)
|
||||
# else
|
||||
# define C4_API
|
||||
# endif
|
||||
# else
|
||||
# define C4_API
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
# define C4_RESTRICT __restrict
|
||||
# define C4_RESTRICT_FN __declspec(restrict)
|
||||
# define C4_NO_INLINE __declspec(noinline)
|
||||
# define C4_ALWAYS_INLINE inline __forceinline
|
||||
/** these are not available in VS AFAIK */
|
||||
# define C4_CONST
|
||||
# define C4_PURE
|
||||
# define C4_FLATTEN
|
||||
# define C4_HOT /** @todo */
|
||||
# define C4_COLD /** @todo */
|
||||
# define C4_ASSUME(...) __assume(__VA_ARGS__)
|
||||
# define C4_EXPECT(x, y) x /** @todo */
|
||||
# define C4_LIKELY(x) x
|
||||
# define C4_UNLIKELY(x) x
|
||||
# define C4_UNREACHABLE() _c4_msvc_unreachable()
|
||||
# define C4_ATTR_FORMAT(...) /** */
|
||||
# define C4_NORETURN [[noreturn]]
|
||||
# if _MSC_VER >= 1700 // VS2012
|
||||
# define C4_NODISCARD _Check_return_
|
||||
# else
|
||||
# define C4_NODISCARD
|
||||
# endif
|
||||
[[noreturn]] __forceinline void _c4_msvc_unreachable() { __assume(false); } ///< https://stackoverflow.com/questions/60802864/emulating-gccs-builtin-unreachable-in-visual-studio
|
||||
# define C4_UNREACHABLE_AFTER_ERR() /* */
|
||||
#else
|
||||
///< @todo assuming gcc-like compiler. check it is actually so.
|
||||
/** for function attributes in GCC,
|
||||
* @see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes */
|
||||
/** for __builtin functions in GCC,
|
||||
* @see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html */
|
||||
# define C4_RESTRICT __restrict__
|
||||
# define C4_RESTRICT_FN __attribute__((restrict))
|
||||
# define C4_NO_INLINE __attribute__((noinline))
|
||||
# define C4_ALWAYS_INLINE inline __attribute__((always_inline))
|
||||
# define C4_CONST __attribute__((const))
|
||||
# define C4_PURE __attribute__((pure))
|
||||
/** force inlining of every callee function */
|
||||
# define C4_FLATTEN __atribute__((flatten))
|
||||
/** mark a function as hot, ie as having a visible impact in CPU time
|
||||
* thus making it more likely to inline, etc
|
||||
* @see http://stackoverflow.com/questions/15028990/semantics-of-gcc-hot-attribute */
|
||||
# define C4_HOT __attribute__((hot))
|
||||
/** mark a function as cold, ie as NOT having a visible impact in CPU time
|
||||
* @see http://stackoverflow.com/questions/15028990/semantics-of-gcc-hot-attribute */
|
||||
# define C4_COLD __attribute__((cold))
|
||||
# define C4_EXPECT(x, y) __builtin_expect(x, y) ///< @see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
|
||||
# define C4_LIKELY(x) __builtin_expect(x, 1)
|
||||
# define C4_UNLIKELY(x) __builtin_expect(x, 0)
|
||||
# define C4_UNREACHABLE() __builtin_unreachable()
|
||||
# define C4_ATTR_FORMAT(...) //__attribute__((format (__VA_ARGS__))) ///< @see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes
|
||||
# define C4_NORETURN __attribute__((noreturn))
|
||||
# define C4_NODISCARD __attribute__((warn_unused_result))
|
||||
# define C4_UNREACHABLE_AFTER_ERR() C4_UNREACHABLE()
|
||||
// C4_ASSUME
|
||||
// see https://stackoverflow.com/questions/63493968/reproducing-clangs-builtin-assume-for-gcc
|
||||
// preferred option: C++ standard attribute
|
||||
# ifdef __has_cpp_attribute
|
||||
# if __has_cpp_attribute(assume) >= 202207L
|
||||
# define C4_ASSUME(...) [[assume(__VA_ARGS__)]]
|
||||
# endif
|
||||
# endif
|
||||
// first fallback: compiler intrinsics/attributes for assumptions
|
||||
# ifndef C4_ASSUME
|
||||
# if defined(__clang__)
|
||||
# define C4_ASSUME(...) __builtin_assume(__VA_ARGS__)
|
||||
# elif defined(__GNUC__)
|
||||
# if __GNUC__ >= 13
|
||||
# define C4_ASSUME(...) __attribute__((__assume__(__VA_ARGS__)))
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
// second fallback: possibly evaluating uses of unreachable()
|
||||
// Set this to 1 if you want to allow assumptions to possibly evaluate.
|
||||
# ifndef C4_ASSUME_ALLOW_EVAL
|
||||
# define C4_ASSUME_ALLOW_EVAL 0
|
||||
# endif
|
||||
# if !defined(C4_ASSUME) && (C4_ASSUME_ALLOW_EVAL)
|
||||
# define C4_ASSUME(...) do { if (!bool(__VA_ARGS__)) C4_UNREACHABLE(); ) while(0)
|
||||
# endif
|
||||
// last fallback: define macro as doing nothing
|
||||
# ifndef C4_ASSUME
|
||||
# define C4_ASSUME(...)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#if C4_CPP >= 14
|
||||
# define C4_DEPRECATED(msg) [[deprecated(msg)]]
|
||||
#else
|
||||
# if defined(_MSC_VER)
|
||||
# define C4_DEPRECATED(msg) __declspec(deprecated(msg))
|
||||
# else // defined(__GNUC__) || defined(__clang__)
|
||||
# define C4_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define C4_FUNC __FUNCTION__
|
||||
# define C4_PRETTY_FUNC __FUNCSIG__
|
||||
#else /// @todo assuming gcc-like compiler. check it is actually so.
|
||||
# define C4_FUNC __FUNCTION__
|
||||
# define C4_PRETTY_FUNC __PRETTY_FUNCTION__
|
||||
#endif
|
||||
|
||||
/** prevent compiler warnings about a specific var being unused */
|
||||
#define C4_UNUSED(var) (void)var
|
||||
|
||||
#if C4_CPP >= 17
|
||||
#define C4_STATIC_ASSERT(cond) static_assert(cond)
|
||||
#else
|
||||
#define C4_STATIC_ASSERT(cond) static_assert((cond), #cond)
|
||||
#endif
|
||||
#define C4_STATIC_ASSERT_MSG(cond, msg) static_assert((cond), #cond ": " msg)
|
||||
|
||||
/** @def C4_DONT_OPTIMIZE idea lifted from GoogleBenchmark.
|
||||
* @see https://github.com/google/benchmark/blob/master/include/benchmark/benchmark_api.h */
|
||||
namespace c4 {
|
||||
namespace detail {
|
||||
#ifdef __GNUC__
|
||||
# define C4_DONT_OPTIMIZE(var) c4::detail::dont_optimize(var)
|
||||
template< class T >
|
||||
C4_ALWAYS_INLINE void dont_optimize(T const& value) { asm volatile("" : : "g"(value) : "memory"); } // NOLINT
|
||||
#else
|
||||
# define C4_DONT_OPTIMIZE(var) c4::detail::use_char_pointer(reinterpret_cast< const char* >(&var))
|
||||
void use_char_pointer(char const volatile*);
|
||||
#endif
|
||||
} // namespace detail
|
||||
} // namespace c4
|
||||
|
||||
/** @def C4_KEEP_EMPTY_LOOP prevent an empty loop from being optimized out.
|
||||
* @see http://stackoverflow.com/a/7084193/5875572 */
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
# define C4_KEEP_EMPTY_LOOP { char c; C4_DONT_OPTIMIZE(c); }
|
||||
#else
|
||||
# define C4_KEEP_EMPTY_LOOP { asm(""); }
|
||||
#endif
|
||||
|
||||
/** @def C4_VA_LIST_REUSE_MUST_COPY
|
||||
* @todo <jpmag> I strongly suspect that this is actually only in UNIX platforms. revisit this. */
|
||||
#ifdef __GNUC__
|
||||
# define C4_VA_LIST_REUSE_MUST_COPY
|
||||
#endif
|
||||
|
||||
#endif /* _C4_LANGUAGE_HPP_ */
|
||||
-782
@@ -1,782 +0,0 @@
|
||||
#ifndef _C4_MEMORY_UTIL_HPP_
|
||||
#define _C4_MEMORY_UTIL_HPP_
|
||||
|
||||
#include "c4/config.hpp"
|
||||
#include "c4/error.hpp"
|
||||
#include "c4/compiler.hpp"
|
||||
#include "c4/cpu.hpp"
|
||||
#ifdef C4_MSVC
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#if (defined(__GNUC__) && __GNUC__ >= 10) || defined(__has_builtin)
|
||||
#define _C4_USE_LSB_INTRINSIC(which) __has_builtin(which)
|
||||
#define _C4_USE_MSB_INTRINSIC(which) __has_builtin(which)
|
||||
#elif defined(C4_MSVC)
|
||||
#define _C4_USE_LSB_INTRINSIC(which) true
|
||||
#define _C4_USE_MSB_INTRINSIC(which) true
|
||||
#else
|
||||
// let's try our luck
|
||||
#define _C4_USE_LSB_INTRINSIC(which) true
|
||||
#define _C4_USE_MSB_INTRINSIC(which) true
|
||||
#endif
|
||||
|
||||
|
||||
/** @file memory_util.hpp Some memory utilities. */
|
||||
|
||||
// NOLINTBEGIN(google-runtime-int)
|
||||
|
||||
namespace c4 {
|
||||
|
||||
C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wold-style-cast")
|
||||
|
||||
/** set the given memory to zero */
|
||||
C4_ALWAYS_INLINE void mem_zero(void* mem, size_t num_bytes)
|
||||
{
|
||||
memset(mem, 0, num_bytes);
|
||||
}
|
||||
/** set the given memory to zero */
|
||||
template<class T>
|
||||
C4_ALWAYS_INLINE void mem_zero(T* mem, size_t num_elms)
|
||||
{
|
||||
memset(mem, 0, sizeof(T) * num_elms);
|
||||
}
|
||||
/** set the given memory to zero */
|
||||
template<class T>
|
||||
C4_ALWAYS_INLINE void mem_zero(T* mem)
|
||||
{
|
||||
memset(mem, 0, sizeof(T));
|
||||
}
|
||||
|
||||
C4_ALWAYS_INLINE C4_CONST bool mem_overlaps(void const* a, void const* b, size_t sza, size_t szb)
|
||||
{
|
||||
// thanks @timwynants
|
||||
return (((const char*)b + szb) > a && b < ((const char*)a+sza));
|
||||
}
|
||||
|
||||
void mem_repeat(void* dest, void const* pattern, size_t pattern_size, size_t num_times);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class T>
|
||||
C4_ALWAYS_INLINE C4_CONST bool is_aligned(T *ptr, uintptr_t alignment=alignof(T))
|
||||
{
|
||||
return (uintptr_t(ptr) & (alignment - uintptr_t(1))) == uintptr_t(0);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// least significant bit
|
||||
|
||||
/** @name msb Compute the least significant bit
|
||||
* @note the input value must be nonzero
|
||||
* @note the input type must be unsigned
|
||||
*/
|
||||
/** @{ */
|
||||
|
||||
// https://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightLinear
|
||||
#define _c4_lsb_fallback \
|
||||
unsigned c = 0; \
|
||||
v = (v ^ (v - 1)) >> 1; /* Set v's trailing 0s to 1s and zero rest */ \
|
||||
for(; v; ++c) \
|
||||
v >>= 1; \
|
||||
return (unsigned) c
|
||||
|
||||
// u8
|
||||
template<class I>
|
||||
C4_CONSTEXPR14
|
||||
auto lsb(I v) noexcept
|
||||
-> typename std::enable_if<sizeof(I) == 1u, unsigned>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_unsigned<I>::value);
|
||||
C4_ASSERT(v != 0);
|
||||
#if _C4_USE_LSB_INTRINSIC(__builtin_ctz)
|
||||
// upcast to use the intrinsic, it's cheaper.
|
||||
#ifdef C4_MSVC
|
||||
#if !defined(C4_CPU_ARM64) && !defined(C4_CPU_ARM)
|
||||
unsigned long bit;
|
||||
_BitScanForward(&bit, (unsigned long)v);
|
||||
return bit;
|
||||
#else
|
||||
_c4_lsb_fallback;
|
||||
#endif
|
||||
#else
|
||||
return (unsigned)__builtin_ctz((unsigned)v);
|
||||
#endif
|
||||
#else
|
||||
_c4_lsb_fallback;
|
||||
#endif
|
||||
}
|
||||
|
||||
// u16
|
||||
template<class I>
|
||||
C4_CONSTEXPR14
|
||||
auto lsb(I v) noexcept
|
||||
-> typename std::enable_if<sizeof(I) == 2u, unsigned>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_unsigned<I>::value);
|
||||
C4_ASSERT(v != 0);
|
||||
#if _C4_USE_LSB_INTRINSIC(__builtin_ctz)
|
||||
// upcast to use the intrinsic, it's cheaper.
|
||||
// Then remember that the upcast makes it to 31bits
|
||||
#ifdef C4_MSVC
|
||||
#if !defined(C4_CPU_ARM64) && !defined(C4_CPU_ARM)
|
||||
unsigned long bit;
|
||||
_BitScanForward(&bit, (unsigned long)v);
|
||||
return bit;
|
||||
#else
|
||||
_c4_lsb_fallback;
|
||||
#endif
|
||||
#else
|
||||
return (unsigned)__builtin_ctz((unsigned)v);
|
||||
#endif
|
||||
#else
|
||||
_c4_lsb_fallback;
|
||||
#endif
|
||||
}
|
||||
|
||||
// u32
|
||||
template<class I>
|
||||
C4_CONSTEXPR14
|
||||
auto lsb(I v) noexcept
|
||||
-> typename std::enable_if<sizeof(I) == 4u, unsigned>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_unsigned<I>::value);
|
||||
C4_ASSERT(v != 0);
|
||||
#if _C4_USE_LSB_INTRINSIC(__builtin_ctz)
|
||||
#ifdef C4_MSVC
|
||||
#if !defined(C4_CPU_ARM64) && !defined(C4_CPU_ARM)
|
||||
unsigned long bit;
|
||||
_BitScanForward(&bit, v);
|
||||
return bit;
|
||||
#else
|
||||
_c4_lsb_fallback;
|
||||
#endif
|
||||
#else
|
||||
return (unsigned)__builtin_ctz((unsigned)v);
|
||||
#endif
|
||||
#else
|
||||
_c4_lsb_fallback;
|
||||
#endif
|
||||
}
|
||||
|
||||
// u64 in 64bits
|
||||
template<class I>
|
||||
C4_CONSTEXPR14
|
||||
auto lsb(I v) noexcept
|
||||
-> typename std::enable_if<sizeof(I) == 8u && sizeof(unsigned long) == 8u, unsigned>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_unsigned<I>::value);
|
||||
C4_ASSERT(v != 0);
|
||||
#if _C4_USE_LSB_INTRINSIC(__builtin_ctzl)
|
||||
#if defined(C4_MSVC)
|
||||
#if !defined(C4_CPU_ARM64) && !defined(C4_CPU_ARM)
|
||||
unsigned long bit;
|
||||
_BitScanForward64(&bit, v);
|
||||
return bit;
|
||||
#else
|
||||
_c4_lsb_fallback;
|
||||
#endif
|
||||
#else
|
||||
return (unsigned)__builtin_ctzl((unsigned long)v);
|
||||
#endif
|
||||
#else
|
||||
_c4_lsb_fallback;
|
||||
#endif
|
||||
}
|
||||
|
||||
// u64 in 32bits
|
||||
template<class I>
|
||||
C4_CONSTEXPR14
|
||||
auto lsb(I v) noexcept
|
||||
-> typename std::enable_if<sizeof(I) == 8u && sizeof(unsigned long long) == 8u && sizeof(unsigned long) != sizeof(unsigned long long), unsigned>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_unsigned<I>::value);
|
||||
C4_ASSERT(v != 0);
|
||||
#if _C4_USE_LSB_INTRINSIC(__builtin_ctzll)
|
||||
#if defined(C4_MSVC)
|
||||
#if !defined(C4_CPU_X86) && !defined(C4_CPU_ARM64) && !defined(C4_CPU_ARM)
|
||||
unsigned long bit;
|
||||
_BitScanForward64(&bit, v);
|
||||
return bit;
|
||||
#else
|
||||
_c4_lsb_fallback;
|
||||
#endif
|
||||
#else
|
||||
return (unsigned)__builtin_ctzll((unsigned long long)v);
|
||||
#endif
|
||||
#else
|
||||
_c4_lsb_fallback;
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef _c4_lsb_fallback
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
namespace detail {
|
||||
template<class I, I val, unsigned num_bits, bool finished> struct _lsb11;
|
||||
template<class I, I val, unsigned num_bits>
|
||||
struct _lsb11<I, val, num_bits, false>
|
||||
{
|
||||
enum : unsigned { num = _lsb11<I, (val>>1), num_bits+I(1), (((val>>1)&I(1))!=I(0))>::num };
|
||||
};
|
||||
template<class I, I val, unsigned num_bits>
|
||||
struct _lsb11<I, val, num_bits, true>
|
||||
{
|
||||
enum : unsigned { num = num_bits };
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
|
||||
/** TMP version of lsb(); this needs to be implemented with template
|
||||
* meta-programming because C++11 cannot use a constexpr function with
|
||||
* local variables
|
||||
* @see lsb */
|
||||
template<class I, I number>
|
||||
struct lsb11
|
||||
{
|
||||
static_assert(number != 0, "lsb: number must be nonzero");
|
||||
enum : unsigned { value = detail::_lsb11<I, number, 0, ((number&I(1))!=I(0))>::num};
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// most significant bit
|
||||
|
||||
|
||||
/** @name msb Compute the most significant bit
|
||||
* @note the input value must be nonzero
|
||||
* @note the input type must be unsigned
|
||||
*/
|
||||
/** @{ */
|
||||
|
||||
|
||||
#define _c4_msb8_fallback \
|
||||
unsigned n = 0; \
|
||||
if(v & I(0xf0)) v >>= 4, n |= I(4); \
|
||||
if(v & I(0x0c)) v >>= 2, n |= I(2); \
|
||||
if(v & I(0x02)) v >>= 1, n |= I(1); \
|
||||
return n
|
||||
|
||||
#define _c4_msb16_fallback \
|
||||
unsigned n = 0; \
|
||||
if(v & I(0xff00)) v >>= 8, n |= I(8); \
|
||||
if(v & I(0x00f0)) v >>= 4, n |= I(4); \
|
||||
if(v & I(0x000c)) v >>= 2, n |= I(2); \
|
||||
if(v & I(0x0002)) v >>= 1, n |= I(1); \
|
||||
return n
|
||||
|
||||
#define _c4_msb32_fallback \
|
||||
unsigned n = 0; \
|
||||
if(v & I(0xffff0000)) v >>= 16, n |= 16; \
|
||||
if(v & I(0x0000ff00)) v >>= 8, n |= 8; \
|
||||
if(v & I(0x000000f0)) v >>= 4, n |= 4; \
|
||||
if(v & I(0x0000000c)) v >>= 2, n |= 2; \
|
||||
if(v & I(0x00000002)) v >>= 1, n |= 1; \
|
||||
return n
|
||||
|
||||
#define _c4_msb64_fallback \
|
||||
unsigned n = 0; \
|
||||
if(v & I(0xffffffff00000000)) v >>= 32, n |= I(32); \
|
||||
if(v & I(0x00000000ffff0000)) v >>= 16, n |= I(16); \
|
||||
if(v & I(0x000000000000ff00)) v >>= 8, n |= I(8); \
|
||||
if(v & I(0x00000000000000f0)) v >>= 4, n |= I(4); \
|
||||
if(v & I(0x000000000000000c)) v >>= 2, n |= I(2); \
|
||||
if(v & I(0x0000000000000002)) v >>= 1, n |= I(1); \
|
||||
return n
|
||||
|
||||
|
||||
// u8
|
||||
template<class I>
|
||||
C4_CONSTEXPR14
|
||||
auto msb(I v) noexcept
|
||||
-> typename std::enable_if<sizeof(I) == 1u, unsigned>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_unsigned<I>::value);
|
||||
C4_ASSERT(v != 0);
|
||||
#if _C4_USE_MSB_INTRINSIC(__builtin_clz)
|
||||
// upcast to use the intrinsic, it's cheaper.
|
||||
// Then remember that the upcast makes it to 31bits
|
||||
#ifdef C4_MSVC
|
||||
#if !defined(C4_CPU_ARM64) && !defined(C4_CPU_ARM)
|
||||
unsigned long bit;
|
||||
_BitScanReverse(&bit, (unsigned long)v);
|
||||
return bit;
|
||||
#else
|
||||
_c4_msb8_fallback;
|
||||
#endif
|
||||
#else
|
||||
return 31u - (unsigned)__builtin_clz((unsigned)v);
|
||||
#endif
|
||||
#else
|
||||
_c4_msb8_fallback;
|
||||
#endif
|
||||
}
|
||||
|
||||
// u16
|
||||
template<class I>
|
||||
C4_CONSTEXPR14
|
||||
auto msb(I v) noexcept
|
||||
-> typename std::enable_if<sizeof(I) == 2u, unsigned>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_unsigned<I>::value);
|
||||
C4_ASSERT(v != 0);
|
||||
#if _C4_USE_MSB_INTRINSIC(__builtin_clz)
|
||||
// upcast to use the intrinsic, it's cheaper.
|
||||
// Then remember that the upcast makes it to 31bits
|
||||
#ifdef C4_MSVC
|
||||
#if !defined(C4_CPU_ARM64) && !defined(C4_CPU_ARM)
|
||||
unsigned long bit;
|
||||
_BitScanReverse(&bit, (unsigned long)v);
|
||||
return bit;
|
||||
#else
|
||||
_c4_msb16_fallback;
|
||||
#endif
|
||||
#else
|
||||
return 31u - (unsigned)__builtin_clz((unsigned)v);
|
||||
#endif
|
||||
#else
|
||||
_c4_msb16_fallback;
|
||||
#endif
|
||||
}
|
||||
|
||||
// u32
|
||||
template<class I>
|
||||
C4_CONSTEXPR14
|
||||
auto msb(I v) noexcept
|
||||
-> typename std::enable_if<sizeof(I) == 4u, unsigned>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_unsigned<I>::value);
|
||||
C4_ASSERT(v != 0);
|
||||
#if _C4_USE_MSB_INTRINSIC(__builtin_clz)
|
||||
#ifdef C4_MSVC
|
||||
#if !defined(C4_CPU_ARM64) && !defined(C4_CPU_ARM)
|
||||
unsigned long bit;
|
||||
_BitScanReverse(&bit, v);
|
||||
return bit;
|
||||
#else
|
||||
_c4_msb32_fallback;
|
||||
#endif
|
||||
#else
|
||||
return 31u - (unsigned)__builtin_clz((unsigned)v);
|
||||
#endif
|
||||
#else
|
||||
_c4_msb32_fallback;
|
||||
#endif
|
||||
}
|
||||
|
||||
// u64 in 64bits
|
||||
template<class I>
|
||||
C4_CONSTEXPR14
|
||||
auto msb(I v) noexcept
|
||||
-> typename std::enable_if<sizeof(I) == 8u && sizeof(unsigned long) == 8u, unsigned>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_unsigned<I>::value);
|
||||
C4_ASSERT(v != 0);
|
||||
#if _C4_USE_MSB_INTRINSIC(__builtin_clzl)
|
||||
#ifdef C4_MSVC
|
||||
#if !defined(C4_CPU_ARM64) && !defined(C4_CPU_ARM)
|
||||
unsigned long bit;
|
||||
_BitScanReverse64(&bit, v);
|
||||
return bit;
|
||||
#else
|
||||
_c4_msb64_fallback;
|
||||
#endif
|
||||
#else
|
||||
return 63u - (unsigned)__builtin_clzl((unsigned long)v);
|
||||
#endif
|
||||
#else
|
||||
_c4_msb64_fallback;
|
||||
#endif
|
||||
}
|
||||
|
||||
// u64 in 32bits
|
||||
template<class I>
|
||||
C4_CONSTEXPR14
|
||||
auto msb(I v) noexcept
|
||||
-> typename std::enable_if<sizeof(I) == 8u && sizeof(unsigned long long) == 8u && sizeof(unsigned long) != sizeof(unsigned long long), unsigned>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_unsigned<I>::value);
|
||||
C4_ASSERT(v != 0);
|
||||
#if _C4_USE_MSB_INTRINSIC(__builtin_clzll)
|
||||
#ifdef C4_MSVC
|
||||
#if !defined(C4_CPU_X86) && !defined(C4_CPU_ARM64) && !defined(C4_CPU_ARM)
|
||||
unsigned long bit;
|
||||
_BitScanReverse64(&bit, v);
|
||||
return bit;
|
||||
#else
|
||||
_c4_msb64_fallback;
|
||||
#endif
|
||||
#else
|
||||
return 63u - (unsigned)__builtin_clzll((unsigned long long)v);
|
||||
#endif
|
||||
#else
|
||||
_c4_msb64_fallback;
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef _c4_msb8_fallback
|
||||
#undef _c4_msb16_fallback
|
||||
#undef _c4_msb32_fallback
|
||||
#undef _c4_msb64_fallback
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
namespace detail {
|
||||
template<class I, I val, I num_bits, bool finished> struct _msb11;
|
||||
template<class I, I val, I num_bits>
|
||||
struct _msb11< I, val, num_bits, false>
|
||||
{
|
||||
enum : unsigned { num = _msb11<I, (val>>1), num_bits+I(1), ((val>>1)==I(0))>::num };
|
||||
};
|
||||
template<class I, I val, I num_bits>
|
||||
struct _msb11<I, val, num_bits, true>
|
||||
{
|
||||
static_assert(val == 0, "bad implementation");
|
||||
enum : unsigned { num = (unsigned)(num_bits-1) };
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
|
||||
/** TMP version of msb(); this needs to be implemented with template
|
||||
* meta-programming because C++11 cannot use a constexpr function with
|
||||
* local variables
|
||||
* @see msb */
|
||||
template<class I, I number>
|
||||
struct msb11
|
||||
{
|
||||
enum : unsigned { value = detail::_msb11<I, number, 0, (number==I(0))>::num };
|
||||
};
|
||||
|
||||
|
||||
|
||||
#undef _C4_USE_LSB_INTRINSIC
|
||||
#undef _C4_USE_MSB_INTRINSIC
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// there is an implicit conversion below; it happens when E or B are
|
||||
// narrower than int, and thus any operation will upcast the result to
|
||||
// int, and then downcast to assign
|
||||
C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wconversion")
|
||||
|
||||
/** integer power; this function is constexpr-14 because of the local
|
||||
* variables */
|
||||
template<class B, class E>
|
||||
C4_CONSTEXPR14 C4_CONST auto ipow(B base, E exponent) noexcept -> typename std::enable_if<std::is_signed<E>::value, B>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_integral<E>::value);
|
||||
B r = B(1);
|
||||
if(exponent >= 0)
|
||||
{
|
||||
for(E e = 0; e < exponent; ++e)
|
||||
r *= base;
|
||||
}
|
||||
else
|
||||
{
|
||||
exponent *= E(-1);
|
||||
for(E e = 0; e < exponent; ++e)
|
||||
r /= base;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/** integer power; this function is constexpr-14 because of the local
|
||||
* variables */
|
||||
template<class B, B base, class E>
|
||||
C4_CONSTEXPR14 C4_CONST auto ipow(E exponent) noexcept -> typename std::enable_if<std::is_signed<E>::value, B>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_integral<E>::value);
|
||||
B r = B(1);
|
||||
if(exponent >= 0)
|
||||
{
|
||||
for(E e = 0; e < exponent; ++e)
|
||||
r *= base;
|
||||
}
|
||||
else
|
||||
{
|
||||
exponent *= E(-1);
|
||||
for(E e = 0; e < exponent; ++e)
|
||||
r /= base;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/** integer power; this function is constexpr-14 because of the local
|
||||
* variables */
|
||||
template<class B, class Base, Base base, class E>
|
||||
C4_CONSTEXPR14 C4_CONST auto ipow(E exponent) noexcept -> typename std::enable_if<std::is_signed<E>::value, B>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_integral<E>::value);
|
||||
B r = B(1);
|
||||
B bbase = B(base);
|
||||
if(exponent >= 0)
|
||||
{
|
||||
for(E e = 0; e < exponent; ++e)
|
||||
r *= bbase;
|
||||
}
|
||||
else
|
||||
{
|
||||
exponent *= E(-1);
|
||||
for(E e = 0; e < exponent; ++e)
|
||||
r /= bbase;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/** integer power; this function is constexpr-14 because of the local
|
||||
* variables */
|
||||
template<class B, class E>
|
||||
C4_CONSTEXPR14 C4_CONST auto ipow(B base, E exponent) noexcept -> typename std::enable_if<!std::is_signed<E>::value, B>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_integral<E>::value);
|
||||
B r = B(1);
|
||||
for(E e = 0; e < exponent; ++e)
|
||||
r *= base;
|
||||
return r;
|
||||
}
|
||||
|
||||
/** integer power; this function is constexpr-14 because of the local
|
||||
* variables */
|
||||
template<class B, B base, class E>
|
||||
C4_CONSTEXPR14 C4_CONST auto ipow(E exponent) noexcept -> typename std::enable_if<!std::is_signed<E>::value, B>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_integral<E>::value);
|
||||
B r = B(1);
|
||||
for(E e = 0; e < exponent; ++e)
|
||||
r *= base;
|
||||
return r;
|
||||
}
|
||||
/** integer power; this function is constexpr-14 because of the local
|
||||
* variables */
|
||||
template<class B, class Base, Base base, class E>
|
||||
C4_CONSTEXPR14 C4_CONST auto ipow(E exponent) noexcept -> typename std::enable_if<!std::is_signed<E>::value, B>::type
|
||||
{
|
||||
C4_STATIC_ASSERT(std::is_integral<E>::value);
|
||||
B r = B(1);
|
||||
B bbase = B(base);
|
||||
for(E e = 0; e < exponent; ++e)
|
||||
r *= bbase;
|
||||
return r;
|
||||
}
|
||||
|
||||
C4_SUPPRESS_WARNING_GCC_CLANG_POP
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** return a mask with all bits set [first_bit,last_bit[; this function
|
||||
* is constexpr-14 because of the local variables */
|
||||
template<class I>
|
||||
C4_CONSTEXPR14 I contiguous_mask(I first_bit, I last_bit)
|
||||
{
|
||||
I r = 0;
|
||||
for(I i = first_bit; i < last_bit; ++i)
|
||||
{
|
||||
r |= (I(1) << i);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class I, I val, I first, I last, bool finished>
|
||||
struct _ctgmsk11;
|
||||
|
||||
template<class I, I val, I first, I last>
|
||||
struct _ctgmsk11< I, val, first, last, true>
|
||||
{
|
||||
enum : I { value = _ctgmsk11<I, val|(I(1)<<first), first+I(1), last, (first+1!=last)>::value };
|
||||
};
|
||||
|
||||
template<class I, I val, I first, I last>
|
||||
struct _ctgmsk11< I, val, first, last, false>
|
||||
{
|
||||
enum : I { value = val };
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
/** TMP version of contiguous_mask(); this needs to be implemented with template
|
||||
* meta-programming because C++11 cannot use a constexpr function with
|
||||
* local variables
|
||||
* @see contiguous_mask */
|
||||
template<class I, I first_bit, I last_bit>
|
||||
struct contiguous_mask11
|
||||
{
|
||||
enum : I { value = detail::_ctgmsk11<I, I(0), first_bit, last_bit, (first_bit!=last_bit)>::value };
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
/** use Empty Base Class Optimization to reduce the size of a pair of
|
||||
* potentially empty types*/
|
||||
|
||||
namespace detail {
|
||||
typedef enum {
|
||||
tpc_same,
|
||||
tpc_same_empty,
|
||||
tpc_both_empty,
|
||||
tpc_first_empty,
|
||||
tpc_second_empty,
|
||||
tpc_general
|
||||
} TightPairCase_e;
|
||||
|
||||
template<class First, class Second>
|
||||
constexpr TightPairCase_e tpc_which_case()
|
||||
{
|
||||
return std::is_same<First, Second>::value ?
|
||||
std::is_empty<First>::value ?
|
||||
tpc_same_empty
|
||||
:
|
||||
tpc_same
|
||||
:
|
||||
std::is_empty<First>::value && std::is_empty<Second>::value ?
|
||||
tpc_both_empty
|
||||
:
|
||||
std::is_empty<First>::value ?
|
||||
tpc_first_empty
|
||||
:
|
||||
std::is_empty<Second>::value ?
|
||||
tpc_second_empty
|
||||
:
|
||||
tpc_general
|
||||
;
|
||||
}
|
||||
|
||||
template<class First, class Second, TightPairCase_e Case>
|
||||
struct tight_pair
|
||||
{
|
||||
private:
|
||||
|
||||
First m_first;
|
||||
Second m_second;
|
||||
|
||||
public:
|
||||
|
||||
using first_type = First;
|
||||
using second_type = Second;
|
||||
|
||||
tight_pair() : m_first(), m_second() {}
|
||||
tight_pair(First const& f, Second const& s) : m_first(f), m_second(s) {}
|
||||
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 First & first () { return m_first; }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 First const& first () const { return m_first; }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second & second() { return m_second; }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second const& second() const { return m_second; }
|
||||
};
|
||||
|
||||
template<class First, class Second>
|
||||
struct tight_pair<First, Second, tpc_same_empty> : public First
|
||||
{
|
||||
static_assert(std::is_same<First, Second>::value, "bad implementation");
|
||||
|
||||
using first_type = First;
|
||||
using second_type = Second;
|
||||
|
||||
tight_pair() : First() {}
|
||||
tight_pair(First const& f, Second const& /*s*/) : First(f) {}
|
||||
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 First & first () { return static_cast<First &>(*this); }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 First const& first () const { return static_cast<First const&>(*this); }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second & second() { return reinterpret_cast<Second &>(*this); } // NOLINT
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second const& second() const { return reinterpret_cast<Second const&>(*this); } // NOLINT
|
||||
};
|
||||
|
||||
template<class First, class Second>
|
||||
struct tight_pair<First, Second, tpc_both_empty> : public First, public Second
|
||||
{
|
||||
using first_type = First;
|
||||
using second_type = Second;
|
||||
|
||||
tight_pair() : First(), Second() {}
|
||||
tight_pair(First const& f, Second const& s) : First(f), Second(s) {}
|
||||
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 First & first () { return static_cast<First &>(*this); }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 First const& first () const { return static_cast<First const&>(*this); }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second & second() { return static_cast<Second &>(*this); }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second const& second() const { return static_cast<Second const&>(*this); }
|
||||
};
|
||||
|
||||
template<class First, class Second>
|
||||
struct tight_pair<First, Second, tpc_same> : public First
|
||||
{
|
||||
Second m_second;
|
||||
|
||||
using first_type = First;
|
||||
using second_type = Second;
|
||||
|
||||
tight_pair() : First() {}
|
||||
tight_pair(First const& f, Second const& s) : First(f), m_second(s) {}
|
||||
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 First & first () { return static_cast<First &>(*this); }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 First const& first () const { return static_cast<First const&>(*this); }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second & second() { return m_second; }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second const& second() const { return m_second; }
|
||||
};
|
||||
|
||||
template<class First, class Second>
|
||||
struct tight_pair<First, Second, tpc_first_empty> : public First
|
||||
{
|
||||
Second m_second;
|
||||
|
||||
using first_type = First;
|
||||
using second_type = Second;
|
||||
|
||||
tight_pair() : First(), m_second() {}
|
||||
tight_pair(First const& f, Second const& s) : First(f), m_second(s) {}
|
||||
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 First & first () { return static_cast<First &>(*this); }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 First const& first () const { return static_cast<First const&>(*this); }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second & second() { return m_second; }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second const& second() const { return m_second; }
|
||||
};
|
||||
|
||||
template<class First, class Second>
|
||||
struct tight_pair<First, Second, tpc_second_empty> : public Second
|
||||
{
|
||||
First m_first;
|
||||
|
||||
using first_type = First;
|
||||
using second_type = Second;
|
||||
|
||||
tight_pair() : Second(), m_first() {}
|
||||
tight_pair(First const& f, Second const& s) : Second(s), m_first(f) {}
|
||||
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 First & first () { return m_first; }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 First const& first () const { return m_first; }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second & second() { return static_cast<Second &>(*this); }
|
||||
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second const& second() const { return static_cast<Second const&>(*this); }
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class First, class Second>
|
||||
using tight_pair = detail::tight_pair<First, Second, detail::tpc_which_case<First,Second>()>;
|
||||
|
||||
C4_SUPPRESS_WARNING_GCC_CLANG_POP
|
||||
|
||||
} // namespace c4
|
||||
|
||||
// NOLINTEND(google-runtime-int)
|
||||
|
||||
#endif /* _C4_MEMORY_UTIL_HPP_ */
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
#ifndef _C4_PLATFORM_HPP_
|
||||
#define _C4_PLATFORM_HPP_
|
||||
|
||||
/** @file platform.hpp Provides platform information macros
|
||||
* @ingroup basic_headers */
|
||||
|
||||
// see also https://sourceforge.net/p/predef/wiki/OperatingSystems/
|
||||
|
||||
#if defined(_WIN64)
|
||||
# define C4_WIN
|
||||
# define C4_WIN64
|
||||
#elif defined(_WIN32)
|
||||
# define C4_WIN
|
||||
# define C4_WIN32
|
||||
#elif defined(__ANDROID__)
|
||||
# define C4_ANDROID
|
||||
#elif defined(__APPLE__)
|
||||
# include "TargetConditionals.h"
|
||||
# if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
|
||||
# define C4_IOS
|
||||
# elif TARGET_OS_MAC || TARGET_OS_OSX
|
||||
# define C4_MACOS
|
||||
# else
|
||||
# error "Unknown Apple platform"
|
||||
# endif
|
||||
#elif defined(__linux__) || defined(__linux)
|
||||
# define C4_UNIX
|
||||
# define C4_LINUX
|
||||
#elif defined(__unix__) || defined(__unix)
|
||||
# define C4_UNIX
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
# define C4_ARM
|
||||
#elif defined(__xtensa__) || defined(__XTENSA__)
|
||||
# define C4_XTENSA
|
||||
#elif defined(SWIG)
|
||||
# define C4_SWIG
|
||||
#else
|
||||
# error "unknown platform"
|
||||
#endif
|
||||
|
||||
#if defined(__posix) || defined(C4_UNIX) || defined(C4_LINUX)
|
||||
# define C4_POSIX
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _C4_PLATFORM_HPP_ */
|
||||
-123
@@ -1,123 +0,0 @@
|
||||
#ifndef _C4_PREPROCESSOR_HPP_
|
||||
#define _C4_PREPROCESSOR_HPP_
|
||||
|
||||
/** @file preprocessor.hpp Contains basic macros and preprocessor utilities.
|
||||
* @ingroup basic_headers */
|
||||
|
||||
#ifdef __clang__
|
||||
/* NOTE: using , ## __VA_ARGS__ to deal with zero-args calls to
|
||||
* variadic macros is not portable, but works in clang, gcc, msvc, icc.
|
||||
* clang requires switching off compiler warnings for pedantic mode.
|
||||
* @see http://stackoverflow.com/questions/32047685/variadic-macro-without-arguments */
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" // warning: token pasting of ',' and __VA_ARGS__ is a GNU extension
|
||||
#elif defined(__GNUC__)
|
||||
/* GCC also issues a warning for zero-args calls to variadic macros.
|
||||
* This warning is switched on with -pedantic and apparently there is no
|
||||
* easy way to turn it off as with clang. But marking this as a system
|
||||
* header works.
|
||||
* @see https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html
|
||||
* @see http://stackoverflow.com/questions/35587137/ */
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#define C4_WIDEN(str) L"" str
|
||||
|
||||
#define C4_COUNTOF(arr) (sizeof(arr)/sizeof((arr)[0]))
|
||||
|
||||
#define C4_EXPAND(arg) arg
|
||||
|
||||
/** useful in some macro calls with template arguments */
|
||||
#define C4_COMMA ,
|
||||
/** useful in some macro calls with template arguments
|
||||
* @see C4_COMMA */
|
||||
#define C4_COMMA_X C4_COMMA
|
||||
|
||||
/** expand and quote */
|
||||
#define C4_XQUOTE(arg) _C4_XQUOTE(arg)
|
||||
#define _C4_XQUOTE(arg) C4_QUOTE(arg)
|
||||
#define C4_QUOTE(arg) #arg
|
||||
|
||||
/** expand and concatenate */
|
||||
#define C4_XCAT(arg1, arg2) _C4_XCAT(arg1, arg2)
|
||||
#define _C4_XCAT(arg1, arg2) C4_CAT(arg1, arg2)
|
||||
#define C4_CAT(arg1, arg2) arg1##arg2
|
||||
|
||||
#define C4_VERSION_CAT(major, minor, patch) ((major)*10000 + (minor)*100 + (patch))
|
||||
|
||||
/** A preprocessor foreach. Spectacular trick taken from:
|
||||
* http://stackoverflow.com/a/1872506/5875572
|
||||
* The first argument is for a macro receiving a single argument,
|
||||
* which will be called with every subsequent argument. There is
|
||||
* currently a limit of 32 arguments, and at least 1 must be provided.
|
||||
*
|
||||
Example:
|
||||
@code{.cpp}
|
||||
struct Example {
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
};
|
||||
// define a one-arg macro to be called
|
||||
#define PRN_STRUCT_OFFSETS(field) PRN_STRUCT_OFFSETS_(Example, field)
|
||||
#define PRN_STRUCT_OFFSETS_(structure, field) printf(C4_XQUOTE(structure) ":" C4_XQUOTE(field)" - offset=%zu\n", offsetof(structure, field));
|
||||
|
||||
// now call the macro for a, b and c
|
||||
C4_FOR_EACH(PRN_STRUCT_OFFSETS, a, b, c);
|
||||
@endcode */
|
||||
#define C4_FOR_EACH(what, ...) C4_FOR_EACH_SEP(what, ;, __VA_ARGS__)
|
||||
|
||||
/** same as C4_FOR_EACH(), but use a custom separator between statements.
|
||||
* If a comma is needed as the separator, use the C4_COMMA macro.
|
||||
* @see C4_FOR_EACH
|
||||
* @see C4_COMMA
|
||||
*/
|
||||
#define C4_FOR_EACH_SEP(what, sep, ...) _C4_FOR_EACH_(_C4_FOR_EACH_NARG(__VA_ARGS__), what, sep, __VA_ARGS__)
|
||||
|
||||
/// @cond dev
|
||||
|
||||
#define _C4_FOR_EACH_01(what, sep, x) what(x) sep
|
||||
#define _C4_FOR_EACH_02(what, sep, x, ...) what(x) sep _C4_FOR_EACH_01(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_03(what, sep, x, ...) what(x) sep _C4_FOR_EACH_02(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_04(what, sep, x, ...) what(x) sep _C4_FOR_EACH_03(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_05(what, sep, x, ...) what(x) sep _C4_FOR_EACH_04(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_06(what, sep, x, ...) what(x) sep _C4_FOR_EACH_05(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_07(what, sep, x, ...) what(x) sep _C4_FOR_EACH_06(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_08(what, sep, x, ...) what(x) sep _C4_FOR_EACH_07(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_09(what, sep, x, ...) what(x) sep _C4_FOR_EACH_08(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_10(what, sep, x, ...) what(x) sep _C4_FOR_EACH_09(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_11(what, sep, x, ...) what(x) sep _C4_FOR_EACH_10(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_12(what, sep, x, ...) what(x) sep _C4_FOR_EACH_11(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_13(what, sep, x, ...) what(x) sep _C4_FOR_EACH_12(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_14(what, sep, x, ...) what(x) sep _C4_FOR_EACH_13(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_15(what, sep, x, ...) what(x) sep _C4_FOR_EACH_14(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_16(what, sep, x, ...) what(x) sep _C4_FOR_EACH_15(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_17(what, sep, x, ...) what(x) sep _C4_FOR_EACH_16(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_18(what, sep, x, ...) what(x) sep _C4_FOR_EACH_17(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_19(what, sep, x, ...) what(x) sep _C4_FOR_EACH_18(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_20(what, sep, x, ...) what(x) sep _C4_FOR_EACH_19(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_21(what, sep, x, ...) what(x) sep _C4_FOR_EACH_20(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_22(what, sep, x, ...) what(x) sep _C4_FOR_EACH_21(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_23(what, sep, x, ...) what(x) sep _C4_FOR_EACH_22(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_24(what, sep, x, ...) what(x) sep _C4_FOR_EACH_23(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_25(what, sep, x, ...) what(x) sep _C4_FOR_EACH_24(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_26(what, sep, x, ...) what(x) sep _C4_FOR_EACH_25(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_27(what, sep, x, ...) what(x) sep _C4_FOR_EACH_26(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_28(what, sep, x, ...) what(x) sep _C4_FOR_EACH_27(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_29(what, sep, x, ...) what(x) sep _C4_FOR_EACH_28(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_30(what, sep, x, ...) what(x) sep _C4_FOR_EACH_29(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_31(what, sep, x, ...) what(x) sep _C4_FOR_EACH_30(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_32(what, sep, x, ...) what(x) sep _C4_FOR_EACH_31(what, sep, __VA_ARGS__)
|
||||
#define _C4_FOR_EACH_NARG(...) _C4_FOR_EACH_NARG_(__VA_ARGS__, _C4_FOR_EACH_RSEQ_N())
|
||||
#define _C4_FOR_EACH_NARG_(...) _C4_FOR_EACH_ARG_N(__VA_ARGS__)
|
||||
#define _C4_FOR_EACH_ARG_N(_01, _02, _03, _04, _05, _06, _07, _08, _09, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, N, ...) N
|
||||
#define _C4_FOR_EACH_RSEQ_N() 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 09, 08, 07, 06, 05, 04, 03, 02, 01
|
||||
#define _C4_FOR_EACH_(N, what, sep, ...) C4_XCAT(_C4_FOR_EACH_, N)(what, sep, __VA_ARGS__)
|
||||
|
||||
/// @endcond
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif /* _C4_PREPROCESSOR_HPP_ */
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
#ifndef _C4_STD_STD_HPP_
|
||||
#define _C4_STD_STD_HPP_
|
||||
|
||||
/** @file std.hpp includes all c4-std interop files */
|
||||
|
||||
#include "c4/std/vector.hpp"
|
||||
#include "c4/std/string.hpp"
|
||||
#include "c4/std/string_view.hpp"
|
||||
#include "c4/std/tuple.hpp"
|
||||
|
||||
#endif // _C4_STD_STD_HPP_
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
#ifndef _C4_STD_STD_FWD_HPP_
|
||||
#define _C4_STD_STD_FWD_HPP_
|
||||
|
||||
/** @file std_fwd.hpp includes all c4-std interop fwd files */
|
||||
|
||||
#include "c4/std/vector_fwd.hpp"
|
||||
#include "c4/std/string_fwd.hpp"
|
||||
//#include "c4/std/tuple_fwd.hpp"
|
||||
|
||||
#endif // _C4_STD_STD_FWD_HPP_
|
||||
-97
@@ -1,97 +0,0 @@
|
||||
#ifndef _C4_STD_STRING_HPP_
|
||||
#define _C4_STD_STRING_HPP_
|
||||
|
||||
/** @file string.hpp */
|
||||
|
||||
#ifndef C4CORE_SINGLE_HEADER
|
||||
#include "c4/substr.hpp"
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace c4 {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** get a writeable view to an existing std::string.
|
||||
* When the string is empty, the returned view will be pointing
|
||||
* at the character with value '\0', but the size will be zero.
|
||||
* @see https://en.cppreference.com/w/cpp/string/basic_string/operator_at
|
||||
*/
|
||||
C4_ALWAYS_INLINE c4::substr to_substr(std::string &s) noexcept
|
||||
{
|
||||
#if C4_CPP < 11
|
||||
#error this function will have undefined behavior
|
||||
#endif
|
||||
// since c++11 it is legal to call s[s.size()].
|
||||
return c4::substr(&s[0], s.size()); // NOLINT(readability-container-data-pointer)
|
||||
}
|
||||
|
||||
/** get a readonly view to an existing std::string.
|
||||
* When the string is empty, the returned view will be pointing
|
||||
* at the character with value '\0', but the size will be zero.
|
||||
* @see https://en.cppreference.com/w/cpp/string/basic_string/operator_at
|
||||
*/
|
||||
C4_ALWAYS_INLINE c4::csubstr to_csubstr(std::string const& s) noexcept
|
||||
{
|
||||
#if C4_CPP < 11
|
||||
#error this function will have undefined behavior
|
||||
#endif
|
||||
// since c++11 it is legal to call s[s.size()].
|
||||
return c4::csubstr(&s[0], s.size()); // NOLINT(readability-container-data-pointer)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
C4_ALWAYS_INLINE bool operator== (c4::csubstr ss, std::string const& s) { return ss.compare(to_csubstr(s)) == 0; }
|
||||
C4_ALWAYS_INLINE bool operator!= (c4::csubstr ss, std::string const& s) { return ss.compare(to_csubstr(s)) != 0; }
|
||||
C4_ALWAYS_INLINE bool operator>= (c4::csubstr ss, std::string const& s) { return ss.compare(to_csubstr(s)) >= 0; }
|
||||
C4_ALWAYS_INLINE bool operator> (c4::csubstr ss, std::string const& s) { return ss.compare(to_csubstr(s)) > 0; }
|
||||
C4_ALWAYS_INLINE bool operator<= (c4::csubstr ss, std::string const& s) { return ss.compare(to_csubstr(s)) <= 0; }
|
||||
C4_ALWAYS_INLINE bool operator< (c4::csubstr ss, std::string const& s) { return ss.compare(to_csubstr(s)) < 0; }
|
||||
|
||||
C4_ALWAYS_INLINE bool operator== (std::string const& s, c4::csubstr ss) { return ss.compare(to_csubstr(s)) == 0; }
|
||||
C4_ALWAYS_INLINE bool operator!= (std::string const& s, c4::csubstr ss) { return ss.compare(to_csubstr(s)) != 0; }
|
||||
C4_ALWAYS_INLINE bool operator>= (std::string const& s, c4::csubstr ss) { return ss.compare(to_csubstr(s)) <= 0; }
|
||||
C4_ALWAYS_INLINE bool operator> (std::string const& s, c4::csubstr ss) { return ss.compare(to_csubstr(s)) < 0; }
|
||||
C4_ALWAYS_INLINE bool operator<= (std::string const& s, c4::csubstr ss) { return ss.compare(to_csubstr(s)) >= 0; }
|
||||
C4_ALWAYS_INLINE bool operator< (std::string const& s, c4::csubstr ss) { return ss.compare(to_csubstr(s)) > 0; }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** copy an std::string to a writeable string view */
|
||||
inline size_t to_chars(c4::substr buf, std::string const& s)
|
||||
{
|
||||
C4_ASSERT(!buf.overlaps(to_csubstr(s)));
|
||||
size_t len = buf.len < s.size() ? buf.len : s.size();
|
||||
// calling memcpy with null strings is undefined behavior
|
||||
// and will wreak havoc in calling code's branches.
|
||||
// see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637
|
||||
if(len)
|
||||
{
|
||||
C4_ASSERT(s.data() != nullptr);
|
||||
C4_ASSERT(buf.str != nullptr);
|
||||
memcpy(buf.str, s.data(), len);
|
||||
}
|
||||
return s.size(); // return the number of needed chars
|
||||
}
|
||||
|
||||
/** copy a string view to an existing std::string */
|
||||
inline bool from_chars(c4::csubstr buf, std::string * s)
|
||||
{
|
||||
s->resize(buf.len);
|
||||
C4_ASSERT(!buf.overlaps(to_csubstr(*s)));
|
||||
// calling memcpy with null strings is undefined behavior
|
||||
// and will wreak havoc in calling code's branches.
|
||||
// see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637
|
||||
if(buf.len)
|
||||
{
|
||||
C4_ASSERT(buf.str != nullptr);
|
||||
memcpy(&(*s)[0], buf.str, buf.len); // NOLINT(readability-container-data-pointer)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace c4
|
||||
|
||||
#endif // _C4_STD_STRING_HPP_
|
||||
@@ -1,59 +0,0 @@
|
||||
#ifndef _C4_STD_STRING_FWD_HPP_
|
||||
#define _C4_STD_STRING_FWD_HPP_
|
||||
|
||||
/** @file string_fwd.hpp */
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#ifndef C4CORE_SINGLE_HEADER
|
||||
#include "c4/substr_fwd.hpp"
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
// forward declarations for std::string
|
||||
#if defined(__GLIBCXX__) || defined(__GLIBCPP__)
|
||||
#include <bits/stringfwd.h> // use the fwd header in glibcxx
|
||||
#elif defined(_LIBCPP_VERSION) || defined(__APPLE_CC__)
|
||||
#include <iosfwd> // use the fwd header in stdlibc++
|
||||
#elif defined(_MSC_VER)
|
||||
#include "c4/error.hpp"
|
||||
//! @todo is there a fwd header in msvc?
|
||||
namespace std {
|
||||
C4_SUPPRESS_WARNING_MSVC_WITH_PUSH(4643) // Forward declaring 'char_traits' in namespace std is not permitted by the C++ Standard.
|
||||
template<typename> struct char_traits;
|
||||
template<typename> class allocator;
|
||||
template<typename _CharT, typename _Traits, typename _Alloc> class basic_string;
|
||||
using string = basic_string<char, char_traits<char>, allocator<char>>;
|
||||
C4_SUPPRESS_WARNING_MSVC_POP
|
||||
} /* namespace std */
|
||||
#else
|
||||
#error "unknown standard library"
|
||||
#endif
|
||||
|
||||
namespace c4 {
|
||||
|
||||
c4::substr to_substr(std::string &s) noexcept;
|
||||
c4::csubstr to_csubstr(std::string const& s) noexcept;
|
||||
|
||||
bool operator== (c4::csubstr ss, std::string const& s);
|
||||
bool operator!= (c4::csubstr ss, std::string const& s);
|
||||
bool operator>= (c4::csubstr ss, std::string const& s);
|
||||
bool operator> (c4::csubstr ss, std::string const& s);
|
||||
bool operator<= (c4::csubstr ss, std::string const& s);
|
||||
bool operator< (c4::csubstr ss, std::string const& s);
|
||||
|
||||
bool operator== (std::string const& s, c4::csubstr ss);
|
||||
bool operator!= (std::string const& s, c4::csubstr ss);
|
||||
bool operator>= (std::string const& s, c4::csubstr ss);
|
||||
bool operator> (std::string const& s, c4::csubstr ss);
|
||||
bool operator<= (std::string const& s, c4::csubstr ss);
|
||||
bool operator< (std::string const& s, c4::csubstr ss);
|
||||
|
||||
size_t to_chars(c4::substr buf, std::string const& s);
|
||||
bool from_chars(c4::csubstr buf, std::string * s);
|
||||
|
||||
} // namespace c4
|
||||
|
||||
#endif // DOXYGEN
|
||||
#endif // _C4_STD_STRING_FWD_HPP_
|
||||
@@ -1,71 +0,0 @@
|
||||
#ifndef _C4_STD_STRING_VIEW_HPP_
|
||||
#define _C4_STD_STRING_VIEW_HPP_
|
||||
|
||||
/** @file string_view.hpp */
|
||||
|
||||
#ifndef C4CORE_SINGLE_HEADER
|
||||
#include "c4/language.hpp"
|
||||
#endif
|
||||
|
||||
#if (C4_CPP >= 17 && defined(__cpp_lib_string_view)) || defined(__DOXYGEN__)
|
||||
|
||||
#ifndef C4CORE_SINGLE_HEADER
|
||||
#include "c4/substr.hpp"
|
||||
#endif
|
||||
|
||||
#include <string_view>
|
||||
|
||||
|
||||
namespace c4 {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** create a csubstr from an existing std::string_view. */
|
||||
C4_ALWAYS_INLINE c4::csubstr to_csubstr(std::string_view s) noexcept
|
||||
{
|
||||
return c4::csubstr(s.data(), s.size());
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
C4_ALWAYS_INLINE bool operator== (c4::csubstr ss, std::string_view s) { return ss.compare(s.data(), s.size()) == 0; }
|
||||
C4_ALWAYS_INLINE bool operator!= (c4::csubstr ss, std::string_view s) { return ss.compare(s.data(), s.size()) != 0; }
|
||||
C4_ALWAYS_INLINE bool operator>= (c4::csubstr ss, std::string_view s) { return ss.compare(s.data(), s.size()) >= 0; }
|
||||
C4_ALWAYS_INLINE bool operator> (c4::csubstr ss, std::string_view s) { return ss.compare(s.data(), s.size()) > 0; }
|
||||
C4_ALWAYS_INLINE bool operator<= (c4::csubstr ss, std::string_view s) { return ss.compare(s.data(), s.size()) <= 0; }
|
||||
C4_ALWAYS_INLINE bool operator< (c4::csubstr ss, std::string_view s) { return ss.compare(s.data(), s.size()) < 0; }
|
||||
|
||||
C4_ALWAYS_INLINE bool operator== (std::string_view s, c4::csubstr ss) { return ss.compare(s.data(), s.size()) == 0; }
|
||||
C4_ALWAYS_INLINE bool operator!= (std::string_view s, c4::csubstr ss) { return ss.compare(s.data(), s.size()) != 0; }
|
||||
C4_ALWAYS_INLINE bool operator<= (std::string_view s, c4::csubstr ss) { return ss.compare(s.data(), s.size()) >= 0; }
|
||||
C4_ALWAYS_INLINE bool operator< (std::string_view s, c4::csubstr ss) { return ss.compare(s.data(), s.size()) > 0; }
|
||||
C4_ALWAYS_INLINE bool operator>= (std::string_view s, c4::csubstr ss) { return ss.compare(s.data(), s.size()) <= 0; }
|
||||
C4_ALWAYS_INLINE bool operator> (std::string_view s, c4::csubstr ss) { return ss.compare(s.data(), s.size()) < 0; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** copy an std::string_view to a writeable substr */
|
||||
inline size_t to_chars(c4::substr buf, std::string_view s)
|
||||
{
|
||||
C4_ASSERT(!buf.overlaps(to_csubstr(s)));
|
||||
size_t sz = s.size();
|
||||
size_t len = buf.len < sz ? buf.len : sz;
|
||||
// calling memcpy with null strings is undefined behavior
|
||||
// and will wreak havoc in calling code's branches.
|
||||
// see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637
|
||||
if(len)
|
||||
{
|
||||
C4_ASSERT(s.data() != nullptr);
|
||||
C4_ASSERT(buf.str != nullptr);
|
||||
memcpy(buf.str, s.data(), len);
|
||||
}
|
||||
return sz; // return the number of needed chars
|
||||
}
|
||||
|
||||
} // namespace c4
|
||||
|
||||
#endif // C4_STRING_VIEW_AVAILABLE
|
||||
|
||||
#endif // _C4_STD_STRING_VIEW_HPP_
|
||||
-184
@@ -1,184 +0,0 @@
|
||||
#ifndef _C4_STD_TUPLE_HPP_
|
||||
#define _C4_STD_TUPLE_HPP_
|
||||
|
||||
/** @file tuple.hpp */
|
||||
|
||||
#ifndef C4CORE_SINGLE_HEADER
|
||||
#include "c4/format.hpp"
|
||||
#endif
|
||||
|
||||
#include <tuple>
|
||||
|
||||
/** this is a work in progress */
|
||||
#undef C4_TUPLE_TO_CHARS
|
||||
|
||||
namespace c4 {
|
||||
|
||||
#ifdef C4_TUPLE_TO_CHARS
|
||||
namespace detail {
|
||||
|
||||
template< size_t Curr, class... Types >
|
||||
struct tuple_helper
|
||||
{
|
||||
static size_t do_cat(substr buf, std::tuple< Types... > const& tp)
|
||||
{
|
||||
size_t num = to_chars(buf, std::get<Curr>(tp));
|
||||
buf = buf.len >= num ? buf.sub(num) : substr{};
|
||||
num += tuple_helper< Curr+1, Types... >::do_cat(buf, tp);
|
||||
return num;
|
||||
}
|
||||
|
||||
static size_t do_uncat(csubstr buf, std::tuple< Types... > & tp)
|
||||
{
|
||||
size_t num = from_str_trim(buf, &std::get<Curr>(tp));
|
||||
if(num == csubstr::npos) return csubstr::npos;
|
||||
buf = buf.len >= num ? buf.sub(num) : substr{};
|
||||
num += tuple_helper< Curr+1, Types... >::do_uncat(buf, tp);
|
||||
return num;
|
||||
}
|
||||
|
||||
template< class Sep >
|
||||
static size_t do_catsep_more(substr buf, Sep const& sep, std::tuple< Types... > const& tp)
|
||||
{
|
||||
size_t ret = to_chars(buf, sep), num = ret;
|
||||
buf = buf.len >= ret ? buf.sub(ret) : substr{};
|
||||
ret = to_chars(buf, std::get<Curr>(tp));
|
||||
num += ret;
|
||||
buf = buf.len >= ret ? buf.sub(ret) : substr{};
|
||||
ret = tuple_helper< Curr+1, Types... >::do_catsep_more(buf, sep, tp);
|
||||
num += ret;
|
||||
return num;
|
||||
}
|
||||
|
||||
template< class Sep >
|
||||
static size_t do_uncatsep_more(csubstr buf, Sep & sep, std::tuple< Types... > & tp)
|
||||
{
|
||||
size_t ret = from_str_trim(buf, &sep), num = ret;
|
||||
if(ret == csubstr::npos) return csubstr::npos;
|
||||
buf = buf.len >= ret ? buf.sub(ret) : substr{};
|
||||
ret = from_str_trim(buf, &std::get<Curr>(tp));
|
||||
if(ret == csubstr::npos) return csubstr::npos;
|
||||
num += ret;
|
||||
buf = buf.len >= ret ? buf.sub(ret) : substr{};
|
||||
ret = tuple_helper< Curr+1, Types... >::do_uncatsep_more(buf, sep, tp);
|
||||
if(ret == csubstr::npos) return csubstr::npos;
|
||||
num += ret;
|
||||
return num;
|
||||
}
|
||||
|
||||
static size_t do_format(substr buf, csubstr fmt, std::tuple< Types... > const& tp)
|
||||
{
|
||||
auto pos = fmt.find("{}");
|
||||
if(pos != csubstr::npos)
|
||||
{
|
||||
size_t num = to_chars(buf, fmt.sub(0, pos));
|
||||
size_t out = num;
|
||||
buf = buf.len >= num ? buf.sub(num) : substr{};
|
||||
num = to_chars(buf, std::get<Curr>(tp));
|
||||
out += num;
|
||||
buf = buf.len >= num ? buf.sub(num) : substr{};
|
||||
num = tuple_helper< Curr+1, Types... >::do_format(buf, fmt.sub(pos + 2), tp);
|
||||
out += num;
|
||||
return out;
|
||||
}
|
||||
else
|
||||
{
|
||||
return format(buf, fmt);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t do_unformat(csubstr buf, csubstr fmt, std::tuple< Types... > & tp)
|
||||
{
|
||||
auto pos = fmt.find("{}");
|
||||
if(pos != csubstr::npos)
|
||||
{
|
||||
size_t num = pos;
|
||||
size_t out = num;
|
||||
buf = buf.len >= num ? buf.sub(num) : substr{};
|
||||
num = from_str_trim(buf, &std::get<Curr>(tp));
|
||||
out += num;
|
||||
buf = buf.len >= num ? buf.sub(num) : substr{};
|
||||
num = tuple_helper< Curr+1, Types... >::do_unformat(buf, fmt.sub(pos + 2), tp);
|
||||
out += num;
|
||||
return out;
|
||||
}
|
||||
else
|
||||
{
|
||||
return tuple_helper< sizeof...(Types), Types... >::do_unformat(buf, fmt, tp);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** @todo VS compilation fails for this class */
|
||||
template< class... Types >
|
||||
struct tuple_helper< sizeof...(Types), Types... >
|
||||
{
|
||||
static size_t do_cat(substr /*buf*/, std::tuple<Types...> const& /*tp*/) { return 0; }
|
||||
static size_t do_uncat(csubstr /*buf*/, std::tuple<Types...> & /*tp*/) { return 0; }
|
||||
|
||||
template< class Sep > static size_t do_catsep_more(substr /*buf*/, Sep const& /*sep*/, std::tuple<Types...> const& /*tp*/) { return 0; }
|
||||
template< class Sep > static size_t do_uncatsep_more(csubstr /*buf*/, Sep & /*sep*/, std::tuple<Types...> & /*tp*/) { return 0; }
|
||||
|
||||
static size_t do_format(substr buf, csubstr fmt, std::tuple<Types...> const& /*tp*/)
|
||||
{
|
||||
return to_chars(buf, fmt);
|
||||
}
|
||||
|
||||
static size_t do_unformat(csubstr buf, csubstr fmt, std::tuple<Types...> const& /*tp*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template< class... Types >
|
||||
inline size_t cat(substr buf, std::tuple< Types... > const& tp)
|
||||
{
|
||||
return detail::tuple_helper< 0, Types... >::do_cat(buf, tp);
|
||||
}
|
||||
|
||||
template< class... Types >
|
||||
inline size_t uncat(csubstr buf, std::tuple< Types... > & tp)
|
||||
{
|
||||
return detail::tuple_helper< 0, Types... >::do_uncat(buf, tp);
|
||||
}
|
||||
|
||||
template< class Sep, class... Types >
|
||||
inline size_t catsep(substr buf, Sep const& sep, std::tuple< Types... > const& tp)
|
||||
{
|
||||
size_t num = to_chars(buf, std::cref(std::get<0>(tp)));
|
||||
buf = buf.len >= num ? buf.sub(num) : substr{};
|
||||
num += detail::tuple_helper< 1, Types... >::do_catsep_more(buf, sep, tp);
|
||||
return num;
|
||||
}
|
||||
|
||||
template< class Sep, class... Types >
|
||||
inline size_t uncatsep(csubstr buf, Sep & sep, std::tuple< Types... > & tp)
|
||||
{
|
||||
size_t ret = from_str_trim(buf, &std::get<0>(tp)), num = ret;
|
||||
if(ret == csubstr::npos) return csubstr::npos;
|
||||
buf = buf.len >= ret ? buf.sub(ret) : substr{};
|
||||
ret = detail::tuple_helper< 1, Types... >::do_uncatsep_more(buf, sep, tp);
|
||||
if(ret == csubstr::npos) return csubstr::npos;
|
||||
num += ret;
|
||||
return num;
|
||||
}
|
||||
|
||||
template< class... Types >
|
||||
inline size_t format(substr buf, csubstr fmt, std::tuple< Types... > const& tp)
|
||||
{
|
||||
return detail::tuple_helper< 0, Types... >::do_format(buf, fmt, tp);
|
||||
}
|
||||
|
||||
template< class... Types >
|
||||
inline size_t unformat(csubstr buf, csubstr fmt, std::tuple< Types... > & tp)
|
||||
{
|
||||
return detail::tuple_helper< 0, Types... >::do_unformat(buf, fmt, tp);
|
||||
}
|
||||
#endif // C4_TUPLE_TO_CHARS
|
||||
|
||||
} // namespace c4
|
||||
|
||||
#endif /* _C4_STD_TUPLE_HPP_ */
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
#ifndef _C4_STD_VECTOR_HPP_
|
||||
#define _C4_STD_VECTOR_HPP_
|
||||
|
||||
/** @file vector.hpp provides conversion and comparison facilities
|
||||
* from/between std::vector<char> to c4::substr and c4::csubstr.
|
||||
* @todo add to_span() and friends
|
||||
*/
|
||||
|
||||
#ifndef C4CORE_SINGLE_HEADER
|
||||
#include "c4/substr.hpp"
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace c4 {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** get a substr (writeable string view) of an existing std::vector<char> */
|
||||
template<class Alloc>
|
||||
c4::substr to_substr(std::vector<char, Alloc> &vec)
|
||||
{
|
||||
char *data = vec.empty() ? nullptr : vec.data(); // data() may or may not return a null pointer.
|
||||
return c4::substr(data, vec.size());
|
||||
}
|
||||
|
||||
/** get a csubstr (read-only string) view of an existing std::vector<char> */
|
||||
template<class Alloc>
|
||||
c4::csubstr to_csubstr(std::vector<char, Alloc> const& vec)
|
||||
{
|
||||
const char *data = vec.empty() ? nullptr : vec.data(); // data() may or may not return a null pointer.
|
||||
return c4::csubstr(data, vec.size());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// comparisons between substrings and std::vector<char>
|
||||
|
||||
template<class Alloc> C4_ALWAYS_INLINE bool operator!= (c4::csubstr ss, std::vector<char, Alloc> const& s) { return ss != to_csubstr(s); }
|
||||
template<class Alloc> C4_ALWAYS_INLINE bool operator== (c4::csubstr ss, std::vector<char, Alloc> const& s) { return ss == to_csubstr(s); }
|
||||
template<class Alloc> C4_ALWAYS_INLINE bool operator>= (c4::csubstr ss, std::vector<char, Alloc> const& s) { return ss >= to_csubstr(s); }
|
||||
template<class Alloc> C4_ALWAYS_INLINE bool operator> (c4::csubstr ss, std::vector<char, Alloc> const& s) { return ss > to_csubstr(s); }
|
||||
template<class Alloc> C4_ALWAYS_INLINE bool operator<= (c4::csubstr ss, std::vector<char, Alloc> const& s) { return ss <= to_csubstr(s); }
|
||||
template<class Alloc> C4_ALWAYS_INLINE bool operator< (c4::csubstr ss, std::vector<char, Alloc> const& s) { return ss < to_csubstr(s); }
|
||||
|
||||
template<class Alloc> C4_ALWAYS_INLINE bool operator!= (std::vector<char, Alloc> const& s, c4::csubstr ss) { return ss != to_csubstr(s); }
|
||||
template<class Alloc> C4_ALWAYS_INLINE bool operator== (std::vector<char, Alloc> const& s, c4::csubstr ss) { return ss == to_csubstr(s); }
|
||||
template<class Alloc> C4_ALWAYS_INLINE bool operator>= (std::vector<char, Alloc> const& s, c4::csubstr ss) { return ss <= to_csubstr(s); }
|
||||
template<class Alloc> C4_ALWAYS_INLINE bool operator> (std::vector<char, Alloc> const& s, c4::csubstr ss) { return ss < to_csubstr(s); }
|
||||
template<class Alloc> C4_ALWAYS_INLINE bool operator<= (std::vector<char, Alloc> const& s, c4::csubstr ss) { return ss >= to_csubstr(s); }
|
||||
template<class Alloc> C4_ALWAYS_INLINE bool operator< (std::vector<char, Alloc> const& s, c4::csubstr ss) { return ss > to_csubstr(s); }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** copy a std::vector<char> to a writeable string view */
|
||||
template<class Alloc>
|
||||
inline size_t to_chars(c4::substr buf, std::vector<char, Alloc> const& s)
|
||||
{
|
||||
C4_ASSERT(!buf.overlaps(to_csubstr(s)));
|
||||
size_t len = buf.len < s.size() ? buf.len : s.size();
|
||||
// calling memcpy with null strings is undefined behavior
|
||||
// and will wreak havoc in calling code's branches.
|
||||
// see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637
|
||||
if(len > 0)
|
||||
{
|
||||
memcpy(buf.str, s.data(), len);
|
||||
}
|
||||
return s.size(); // return the number of needed chars
|
||||
}
|
||||
|
||||
/** copy a string view to an existing std::vector<char> */
|
||||
template<class Alloc>
|
||||
inline bool from_chars(c4::csubstr buf, std::vector<char, Alloc> * s)
|
||||
{
|
||||
s->resize(buf.len);
|
||||
C4_ASSERT(!buf.overlaps(to_csubstr(*s)));
|
||||
// calling memcpy with null strings is undefined behavior
|
||||
// and will wreak havoc in calling code's branches.
|
||||
// see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637
|
||||
if(buf.len > 0)
|
||||
{
|
||||
memcpy(&(*s)[0], buf.str, buf.len); // NOLINT(readability-container-data-pointer)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace c4
|
||||
|
||||
#endif // _C4_STD_VECTOR_HPP_
|
||||
@@ -1,70 +0,0 @@
|
||||
#ifndef _C4_STD_VECTOR_FWD_HPP_
|
||||
#define _C4_STD_VECTOR_FWD_HPP_
|
||||
|
||||
/** @file vector_fwd.hpp */
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
// NOLINTBEGIN(cert-dcl58-cpp)
|
||||
|
||||
// forward declarations for std::vector
|
||||
#if defined(__GLIBCXX__) || defined(__GLIBCPP__) || defined(_MSC_VER)
|
||||
#if defined(_MSC_VER)
|
||||
__pragma(warning(push))
|
||||
__pragma(warning(disable : 4643))
|
||||
#endif
|
||||
namespace std {
|
||||
template<typename> class allocator;
|
||||
#ifdef _GLIBCXX_DEBUG
|
||||
inline namespace __debug {
|
||||
template<typename T, typename Alloc> class vector;
|
||||
}
|
||||
#else
|
||||
template<typename T, typename Alloc> class vector;
|
||||
#endif
|
||||
} // namespace std
|
||||
#if defined(_MSC_VER)
|
||||
__pragma(warning(pop))
|
||||
#endif
|
||||
#elif defined(_LIBCPP_ABI_NAMESPACE)
|
||||
namespace std {
|
||||
inline namespace _LIBCPP_ABI_NAMESPACE {
|
||||
template<typename> class allocator;
|
||||
template<typename T, typename Alloc> class vector;
|
||||
} // namespace _LIBCPP_ABI_NAMESPACE
|
||||
} // namespace std
|
||||
#else
|
||||
#error "unknown standard library"
|
||||
#endif
|
||||
|
||||
#ifndef C4CORE_SINGLE_HEADER
|
||||
#include "c4/substr_fwd.hpp"
|
||||
#endif
|
||||
|
||||
namespace c4 {
|
||||
|
||||
template<class Alloc> c4::substr to_substr(std::vector<char, Alloc> &vec);
|
||||
template<class Alloc> c4::csubstr to_csubstr(std::vector<char, Alloc> const& vec);
|
||||
|
||||
template<class Alloc> bool operator!= (c4::csubstr ss, std::vector<char, Alloc> const& s);
|
||||
template<class Alloc> bool operator== (c4::csubstr ss, std::vector<char, Alloc> const& s);
|
||||
template<class Alloc> bool operator>= (c4::csubstr ss, std::vector<char, Alloc> const& s);
|
||||
template<class Alloc> bool operator> (c4::csubstr ss, std::vector<char, Alloc> const& s);
|
||||
template<class Alloc> bool operator<= (c4::csubstr ss, std::vector<char, Alloc> const& s);
|
||||
template<class Alloc> bool operator< (c4::csubstr ss, std::vector<char, Alloc> const& s);
|
||||
|
||||
template<class Alloc> bool operator!= (std::vector<char, Alloc> const& s, c4::csubstr ss);
|
||||
template<class Alloc> bool operator== (std::vector<char, Alloc> const& s, c4::csubstr ss);
|
||||
template<class Alloc> bool operator>= (std::vector<char, Alloc> const& s, c4::csubstr ss);
|
||||
template<class Alloc> bool operator> (std::vector<char, Alloc> const& s, c4::csubstr ss);
|
||||
template<class Alloc> bool operator<= (std::vector<char, Alloc> const& s, c4::csubstr ss);
|
||||
template<class Alloc> bool operator< (std::vector<char, Alloc> const& s, c4::csubstr ss);
|
||||
|
||||
template<class Alloc> size_t to_chars(c4::substr buf, std::vector<char, Alloc> const& s);
|
||||
template<class Alloc> bool from_chars(c4::csubstr buf, std::vector<char, Alloc> * s);
|
||||
|
||||
} // namespace c4
|
||||
|
||||
// NOLINTEND(cert-dcl58-cpp)
|
||||
|
||||
#endif // _C4_STD_VECTOR_FWD_HPP_
|
||||
-2290
File diff suppressed because it is too large
Load Diff
-16
@@ -1,16 +0,0 @@
|
||||
#ifndef _C4_SUBSTR_FWD_HPP_
|
||||
#define _C4_SUBSTR_FWD_HPP_
|
||||
|
||||
#include "c4/export.hpp"
|
||||
|
||||
namespace c4 {
|
||||
|
||||
#ifndef DOXYGEN
|
||||
template<class C> struct basic_substring;
|
||||
using csubstr = C4CORE_EXPORT basic_substring<const char>;
|
||||
using substr = C4CORE_EXPORT basic_substring<char>;
|
||||
#endif // !DOXYGEN
|
||||
|
||||
} // namespace c4
|
||||
|
||||
#endif /* _C4_SUBSTR_FWD_HPP_ */
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
#ifndef _C4_SZCONV_HPP_
|
||||
#define _C4_SZCONV_HPP_
|
||||
|
||||
/** @file szconv.hpp utilities to deal safely with narrowing conversions */
|
||||
|
||||
#include "c4/config.hpp"
|
||||
#include "c4/error.hpp"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace c4 {
|
||||
|
||||
C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wold-style-cast")
|
||||
|
||||
/** @todo this would be so much easier with calls to numeric_limits::max()... */
|
||||
template<class SizeOut, class SizeIn>
|
||||
struct is_narrower_size : std::conditional
|
||||
<
|
||||
(std::is_signed<SizeOut>::value == std::is_signed<SizeIn>::value)
|
||||
?
|
||||
(sizeof(SizeOut) < sizeof(SizeIn))
|
||||
:
|
||||
(
|
||||
(sizeof(SizeOut) < sizeof(SizeIn))
|
||||
||
|
||||
(
|
||||
(sizeof(SizeOut) == sizeof(SizeIn))
|
||||
&&
|
||||
(std::is_signed<SizeOut>::value && std::is_unsigned<SizeIn>::value)
|
||||
)
|
||||
),
|
||||
std::true_type,
|
||||
std::false_type
|
||||
>::type
|
||||
{
|
||||
static_assert(std::is_integral<SizeIn >::value, "must be integral type");
|
||||
static_assert(std::is_integral<SizeOut>::value, "must be integral type");
|
||||
};
|
||||
|
||||
|
||||
/** when SizeOut is wider than SizeIn, assignment can occur without reservations */
|
||||
template<class SizeOut, class SizeIn>
|
||||
C4_ALWAYS_INLINE
|
||||
typename std::enable_if< ! is_narrower_size<SizeOut, SizeIn>::value, SizeOut>::type
|
||||
szconv(SizeIn sz) noexcept
|
||||
{
|
||||
return static_cast<SizeOut>(sz);
|
||||
}
|
||||
|
||||
/** when SizeOut is narrower than SizeIn, narrowing will occur, so we check
|
||||
* for overflow. Note that this check is done only if C4_XASSERT is enabled.
|
||||
* @see C4_XASSERT */
|
||||
template<class SizeOut, class SizeIn>
|
||||
C4_ALWAYS_INLINE
|
||||
typename std::enable_if<is_narrower_size<SizeOut, SizeIn>::value, SizeOut>::type
|
||||
szconv(SizeIn sz)
|
||||
{
|
||||
C4_XASSERT(sz >= 0);
|
||||
C4_XASSERT_MSG((SizeIn)sz <= (SizeIn)std::numeric_limits<SizeOut>::max(), "size conversion overflow: in=%zu", (size_t)sz);
|
||||
SizeOut szo = static_cast<SizeOut>(sz);
|
||||
return szo;
|
||||
}
|
||||
|
||||
C4_SUPPRESS_WARNING_GCC_CLANG_POP
|
||||
|
||||
} // namespace c4
|
||||
|
||||
#endif /* _C4_SZCONV_HPP_ */
|
||||
-507
@@ -1,507 +0,0 @@
|
||||
#ifndef _C4_TYPES_HPP_
|
||||
#define _C4_TYPES_HPP_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <type_traits>
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#include <utility> // for integer_sequence and friends
|
||||
#endif
|
||||
|
||||
#include "c4/preprocessor.hpp"
|
||||
#include "c4/language.hpp"
|
||||
|
||||
/** @file types.hpp basic types, and utility macros and traits for types.
|
||||
* @ingroup basic_headers */
|
||||
|
||||
/** @defgroup types Type utilities */
|
||||
|
||||
// NOLINTBEGIN(bugprone-macro-parentheses)
|
||||
|
||||
namespace c4 {
|
||||
|
||||
/** @defgroup intrinsic_types Intrinsic types
|
||||
* @ingroup types
|
||||
* @{ */
|
||||
|
||||
using cbyte = const char; /**< a constant byte */
|
||||
using byte = char; /**< a mutable byte */
|
||||
|
||||
using i8 = int8_t;
|
||||
using i16 = int16_t;
|
||||
using i32 = int32_t;
|
||||
using i64 = int64_t;
|
||||
using u8 = uint8_t;
|
||||
using u16 = uint16_t;
|
||||
using u32 = uint32_t;
|
||||
using u64 = uint64_t;
|
||||
|
||||
using f32 = float;
|
||||
using f64 = double;
|
||||
|
||||
using ssize_t = typename std::make_signed<size_t>::type;
|
||||
|
||||
/** @} */
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
/** @defgroup utility_types Utility types
|
||||
* @ingroup types
|
||||
* @{ */
|
||||
|
||||
// some tag types
|
||||
|
||||
#if !defined(__clang__) && defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#if __GNUC__ >= 6
|
||||
#pragma GCC diagnostic ignored "-Wunused-const-variable"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** a tag type for initializing the containers with variadic arguments a la
|
||||
* initializer_list, minus the initializer_list overload problems.
|
||||
*/
|
||||
struct aggregate_t {};
|
||||
/** @see aggregate_t */
|
||||
constexpr const aggregate_t aggregate{};
|
||||
|
||||
/** a tag type for specifying the initial capacity of allocatable contiguous storage */
|
||||
struct with_capacity_t {};
|
||||
/** @see with_capacity_t */
|
||||
constexpr const with_capacity_t with_capacity{};
|
||||
|
||||
/** a tag type for disambiguating template parameter packs in variadic template overloads */
|
||||
struct varargs_t {};
|
||||
/** @see with_capacity_t */
|
||||
constexpr const varargs_t varargs{};
|
||||
|
||||
#if !defined(__clang__) && defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
/** whether a value should be used in place of a const-reference in argument passing. */
|
||||
template<class T>
|
||||
struct cref_uses_val
|
||||
{
|
||||
enum { value = (
|
||||
std::is_scalar<T>::value
|
||||
||
|
||||
(
|
||||
#if C4_CPP >= 20
|
||||
(std::is_trivially_copyable<T>::value && std::is_standard_layout<T>::value)
|
||||
#else
|
||||
std::is_pod<T>::value
|
||||
#endif
|
||||
&&
|
||||
sizeof(T) <= sizeof(size_t))) };
|
||||
};
|
||||
/** utility macro to override the default behaviour for c4::fastcref<T>
|
||||
@see fastcref */
|
||||
#define C4_CREF_USES_VAL(T) \
|
||||
template<> \
|
||||
struct cref_uses_val<T> \
|
||||
{ \
|
||||
enum { value = true }; \
|
||||
};
|
||||
|
||||
/** Whether to use pass-by-value or pass-by-const-reference in a function argument
|
||||
* or return type. */
|
||||
template<class T>
|
||||
using fastcref = typename std::conditional<c4::cref_uses_val<T>::value, T, T const&>::type;
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
/** Just what its name says. Useful sometimes as a default empty policy class. */
|
||||
struct EmptyStruct // NOLINT
|
||||
{
|
||||
template<class... T> EmptyStruct(T && ...){} // NOLINT
|
||||
};
|
||||
|
||||
/** Just what its name says. Useful sometimes as a default policy class to
|
||||
* be inherited from. */
|
||||
struct EmptyStructVirtual // NOLINT
|
||||
{
|
||||
virtual ~EmptyStructVirtual() = default;
|
||||
template<class... T> EmptyStructVirtual(T && ...){} // NOLINT
|
||||
};
|
||||
|
||||
|
||||
/** */
|
||||
template<class T>
|
||||
struct inheritfrom : public T {};
|
||||
|
||||
//--------------------------------------------------
|
||||
// Utilities to make a class obey size restrictions (eg, min size or size multiple of).
|
||||
// DirectX usually makes this restriction with uniform buffers.
|
||||
// This is also useful for padding to prevent false-sharing.
|
||||
|
||||
/** how many bytes must be added to size such that the result is at least minsize? */
|
||||
C4_ALWAYS_INLINE constexpr size_t min_remainder(size_t size, size_t minsize) noexcept
|
||||
{
|
||||
return size < minsize ? minsize-size : 0;
|
||||
}
|
||||
|
||||
/** how many bytes must be added to size such that the result is a multiple of multipleof? */
|
||||
C4_ALWAYS_INLINE constexpr size_t mult_remainder(size_t size, size_t multipleof) noexcept
|
||||
{
|
||||
return (((size % multipleof) != 0) ? (multipleof-(size % multipleof)) : 0);
|
||||
}
|
||||
|
||||
/* force the following class to be tightly packed. */
|
||||
#pragma pack(push, 1)
|
||||
/** pad a class with more bytes at the end.
|
||||
* @see http://stackoverflow.com/questions/21092415/force-c-structure-to-pack-tightly */
|
||||
template<class T, size_t BytesToPadAtEnd>
|
||||
struct Padded : public T
|
||||
{
|
||||
using T::T;
|
||||
using T::operator=;
|
||||
Padded(T const& val) : T(val) {}
|
||||
Padded(T && val) : T(std::forward<T>(val)) {} // NOLINT
|
||||
char ___c4padspace___[BytesToPadAtEnd];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
/** When the padding argument is 0, we cannot declare the char[] array. */
|
||||
template<class T>
|
||||
struct Padded<T, 0> : public T
|
||||
{
|
||||
using T::T;
|
||||
using T::operator=;
|
||||
Padded(T const& val) : T(val) {}
|
||||
Padded(T && val) : T(std::forward<T>(val)) {} // NOLINT
|
||||
};
|
||||
|
||||
/** make T have a size which is at least Min bytes */
|
||||
template<class T, size_t Min>
|
||||
using MinSized = Padded<T, min_remainder(sizeof(T), Min)>;
|
||||
|
||||
/** make T have a size which is a multiple of Mult bytes */
|
||||
template<class T, size_t Mult>
|
||||
using MultSized = Padded<T, mult_remainder(sizeof(T), Mult)>;
|
||||
|
||||
/** make T have a size which is simultaneously:
|
||||
* -bigger or equal than Min
|
||||
* -a multiple of Mult */
|
||||
template<class T, size_t Min, size_t Mult>
|
||||
using MinMultSized = MultSized<MinSized<T, Min>, Mult>;
|
||||
|
||||
/** make T be suitable for use as a uniform buffer. (at least with DirectX). */
|
||||
template<class T>
|
||||
using UbufSized = MinMultSized<T, 64, 16>;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define C4_NO_COPY_CTOR(ty) ty(ty const&) = delete
|
||||
#define C4_NO_MOVE_CTOR(ty) ty(ty &&) = delete
|
||||
#define C4_NO_COPY_ASSIGN(ty) ty& operator=(ty const&) = delete
|
||||
#define C4_NO_MOVE_ASSIGN(ty) ty& operator=(ty &&) = delete
|
||||
#define C4_DEFAULT_COPY_CTOR(ty) ty(ty const&) noexcept = default
|
||||
#define C4_DEFAULT_MOVE_CTOR(ty) ty(ty &&) noexcept = default
|
||||
#define C4_DEFAULT_COPY_ASSIGN(ty) ty& operator=(ty const&) noexcept = default
|
||||
#define C4_DEFAULT_MOVE_ASSIGN(ty) ty& operator=(ty &&) noexcept = default
|
||||
|
||||
#define C4_NO_COPY_OR_MOVE_CTOR(ty) \
|
||||
C4_NO_COPY_CTOR(ty); \
|
||||
C4_NO_MOVE_CTOR(ty)
|
||||
|
||||
#define C4_NO_COPY_OR_MOVE_ASSIGN(ty) \
|
||||
C4_NO_COPY_ASSIGN(ty); \
|
||||
C4_NO_MOVE_ASSIGN(ty)
|
||||
|
||||
#define C4_NO_COPY_OR_MOVE(ty) \
|
||||
C4_NO_COPY_OR_MOVE_CTOR(ty); \
|
||||
C4_NO_COPY_OR_MOVE_ASSIGN(ty)
|
||||
|
||||
#define C4_DEFAULT_COPY_AND_MOVE_CTOR(ty) \
|
||||
C4_DEFAULT_COPY_CTOR(ty); \
|
||||
C4_DEFAULT_MOVE_CTOR(ty)
|
||||
|
||||
#define C4_DEFAULT_COPY_AND_MOVE_ASSIGN(ty) \
|
||||
C4_DEFAULT_COPY_ASSIGN(ty); \
|
||||
C4_DEFAULT_MOVE_ASSIGN(ty)
|
||||
|
||||
#define C4_DEFAULT_COPY_AND_MOVE(ty) \
|
||||
C4_DEFAULT_COPY_AND_MOVE_CTOR(ty); \
|
||||
C4_DEFAULT_COPY_AND_MOVE_ASSIGN(ty)
|
||||
|
||||
/** @see https://en.cppreference.com/w/cpp/named_req/TriviallyCopyable */
|
||||
#define C4_MUST_BE_TRIVIAL_COPY(ty) \
|
||||
static_assert(std::is_trivially_copyable<ty>::value, #ty " must be trivially copyable")
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** @defgroup traits_types Type traits utilities
|
||||
* @ingroup types
|
||||
* @{ */
|
||||
|
||||
// http://stackoverflow.com/questions/10821380/is-t-an-instance-of-a-template-in-c
|
||||
template<template<typename...> class X, typename T> struct is_instance_of_tpl : std::false_type {};
|
||||
template<template<typename...> class X, typename... Y> struct is_instance_of_tpl<X, X<Y...>> : std::true_type {};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** SFINAE. use this macro to enable a template function overload
|
||||
based on a compile-time condition.
|
||||
@code
|
||||
// define an overload for a non-pod type
|
||||
template<class T, C4_REQUIRE_T(std::is_pod<T>::value)>
|
||||
void foo() { std::cout << "pod type\n"; }
|
||||
|
||||
// define an overload for a non-pod type
|
||||
template<class T, C4_REQUIRE_T(!std::is_pod<T>::value)>
|
||||
void foo() { std::cout << "nonpod type\n"; }
|
||||
|
||||
struct non_pod
|
||||
{
|
||||
non_pod() : name("asdfkjhasdkjh") {}
|
||||
const char *name;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
foo<float>(); // prints "pod type"
|
||||
foo<non_pod>(); // prints "nonpod type"
|
||||
}
|
||||
@endcode */
|
||||
#define C4_REQUIRE_T(cond) typename std::enable_if<cond, bool>::type* = nullptr
|
||||
|
||||
/** enable_if for a return type
|
||||
* @see C4_REQUIRE_T */
|
||||
#define C4_REQUIRE_R(cond, type_) typename std::enable_if<cond, type_>::type
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** define a traits class reporting whether a type provides a member typedef */
|
||||
#define C4_DEFINE_HAS_TYPEDEF(member_typedef) \
|
||||
template<typename T> \
|
||||
struct has_##stype \
|
||||
{ \
|
||||
private: \
|
||||
\
|
||||
typedef char yes; \
|
||||
typedef struct { char array[2]; } no; \
|
||||
\
|
||||
template<typename C> \
|
||||
static yes _test(typename C::member_typedef*); \
|
||||
\
|
||||
template<typename C> \
|
||||
static no _test(...); \
|
||||
\
|
||||
public: \
|
||||
\
|
||||
enum { value = (sizeof(_test<T>(0)) == sizeof(yes)) }; \
|
||||
\
|
||||
}
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
/** @defgroup type_declarations Type declaration utilities
|
||||
* @ingroup types
|
||||
* @{ */
|
||||
|
||||
#define _c4_DEFINE_ARRAY_TYPES_WITHOUT_ITERATOR(T, I) \
|
||||
\
|
||||
using size_type = I; \
|
||||
using ssize_type = typename std::make_signed<I>::type; \
|
||||
using difference_type = typename std::make_signed<I>::type; \
|
||||
\
|
||||
using value_type = T; \
|
||||
using pointer = T*; \
|
||||
using const_pointer = T const*; \
|
||||
using reference = T&; \
|
||||
using const_reference = T const&
|
||||
|
||||
#define _c4_DEFINE_TUPLE_ARRAY_TYPES_WITHOUT_ITERATOR(interior_types, I) \
|
||||
\
|
||||
using size_type = I; \
|
||||
using ssize_type = typename std::make_signed<I>::type; \
|
||||
using difference_type = typename std::make_signed<I>::type; \
|
||||
\
|
||||
template<I n> using value_type = typename std::tuple_element< n, std::tuple<interior_types...>>::type; \
|
||||
template<I n> using pointer = value_type<n>*; \
|
||||
template<I n> using const_pointer = value_type<n> const*; \
|
||||
template<I n> using reference = value_type<n>&; \
|
||||
template<I n> using const_reference = value_type<n> const&
|
||||
|
||||
|
||||
#define _c4_DEFINE_ARRAY_TYPES(T, I) \
|
||||
\
|
||||
_c4_DEFINE_ARRAY_TYPES_WITHOUT_ITERATOR(T, I); \
|
||||
\
|
||||
using iterator = T*; \
|
||||
using const_iterator = T const*; \
|
||||
using reverse_iterator = std::reverse_iterator<T*>; \
|
||||
using const_reverse_iterator = std::reverse_iterator<T const*>
|
||||
|
||||
|
||||
#define _c4_DEFINE_TUPLE_ARRAY_TYPES(interior_types, I) \
|
||||
\
|
||||
_c4_DEFINE_TUPLE_ARRAY_TYPES_WITHOUT_ITERATOR(interior_types, I); \
|
||||
\
|
||||
template<I n> using iterator = value_type<n>*; \
|
||||
template<I n> using const_iterator = value_type<n> const*; \
|
||||
template<I n> using reverse_iterator = std::reverse_iterator< value_type<n>*>; \
|
||||
template<I n> using const_reverse_iterator = std::reverse_iterator< value_type<n> const*>
|
||||
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
/** @defgroup compatility_utilities Backport implementation of some Modern C++ utilities
|
||||
* @ingroup types
|
||||
* @{ */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// index_sequence and friends are available only for C++14 and later.
|
||||
// A C++11 implementation is provided here.
|
||||
// This implementation was copied over from clang.
|
||||
// see http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/utility?revision=211563&view=markup#l687
|
||||
|
||||
#if __cplusplus > 201103L
|
||||
|
||||
using std::integer_sequence;
|
||||
using std::index_sequence;
|
||||
using std::make_integer_sequence;
|
||||
using std::make_index_sequence;
|
||||
using std::index_sequence_for;
|
||||
|
||||
#else
|
||||
|
||||
/** C++11 implementation of integer sequence
|
||||
* @see https://en.cppreference.com/w/cpp/utility/integer_sequence
|
||||
* @see taken from clang: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/utility?revision=211563&view=markup#l687 */
|
||||
template<class _Tp, _Tp... _Ip>
|
||||
struct integer_sequence
|
||||
{
|
||||
static_assert(std::is_integral<_Tp>::value,
|
||||
"std::integer_sequence can only be instantiated with an integral type" );
|
||||
using value_type = _Tp;
|
||||
static constexpr size_t size() noexcept { return sizeof...(_Ip); }
|
||||
};
|
||||
|
||||
/** C++11 implementation of index sequence
|
||||
* @see https://en.cppreference.com/w/cpp/utility/integer_sequence
|
||||
* @see taken from clang: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/utility?revision=211563&view=markup#l687 */
|
||||
template<size_t... _Ip>
|
||||
using index_sequence = integer_sequence<size_t, _Ip...>;
|
||||
|
||||
/** @cond DONT_DOCUMENT_THIS */
|
||||
namespace __detail {
|
||||
|
||||
template<typename _Tp, size_t ..._Extra>
|
||||
struct __repeat;
|
||||
|
||||
template<typename _Tp, _Tp ..._Np, size_t ..._Extra>
|
||||
struct __repeat<integer_sequence<_Tp, _Np...>, _Extra...>
|
||||
{
|
||||
using type = integer_sequence<_Tp,
|
||||
_Np...,
|
||||
sizeof...(_Np) + _Np...,
|
||||
2 * sizeof...(_Np) + _Np...,
|
||||
3 * sizeof...(_Np) + _Np...,
|
||||
4 * sizeof...(_Np) + _Np...,
|
||||
5 * sizeof...(_Np) + _Np...,
|
||||
6 * sizeof...(_Np) + _Np...,
|
||||
7 * sizeof...(_Np) + _Np...,
|
||||
_Extra...>;
|
||||
};
|
||||
|
||||
template<size_t _Np> struct __parity;
|
||||
template<size_t _Np> struct __make : __parity<_Np % 8>::template __pmake<_Np> {};
|
||||
|
||||
template<> struct __make<0> { using type = integer_sequence<size_t>; };
|
||||
template<> struct __make<1> { using type = integer_sequence<size_t, 0>; };
|
||||
template<> struct __make<2> { using type = integer_sequence<size_t, 0, 1>; };
|
||||
template<> struct __make<3> { using type = integer_sequence<size_t, 0, 1, 2>; };
|
||||
template<> struct __make<4> { using type = integer_sequence<size_t, 0, 1, 2, 3>; };
|
||||
template<> struct __make<5> { using type = integer_sequence<size_t, 0, 1, 2, 3, 4>; };
|
||||
template<> struct __make<6> { using type = integer_sequence<size_t, 0, 1, 2, 3, 4, 5>; };
|
||||
template<> struct __make<7> { using type = integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6>; };
|
||||
|
||||
template<> struct __parity<0> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type> {}; };
|
||||
template<> struct __parity<1> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1> {}; };
|
||||
template<> struct __parity<2> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1> {}; };
|
||||
template<> struct __parity<3> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1> {}; };
|
||||
template<> struct __parity<4> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
|
||||
template<> struct __parity<5> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
|
||||
template<> struct __parity<6> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
|
||||
template<> struct __parity<7> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
|
||||
|
||||
template<typename _Tp, typename _Up>
|
||||
struct __convert
|
||||
{
|
||||
template<typename> struct __result;
|
||||
template<_Tp ..._Np> struct __result<integer_sequence<_Tp, _Np...>>
|
||||
{
|
||||
using type = integer_sequence<_Up, _Np...>;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
struct __convert<_Tp, _Tp>
|
||||
{
|
||||
template<typename _Up> struct __result
|
||||
{
|
||||
using type = _Up;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename _Tp, _Tp _Np>
|
||||
using __make_integer_sequence_unchecked = typename __detail::__convert<size_t, _Tp>::template __result<typename __detail::__make<_Np>::type>::type;
|
||||
|
||||
template<class _Tp, _Tp _Ep>
|
||||
struct __make_integer_sequence
|
||||
{
|
||||
static_assert(std::is_integral<_Tp>::value,
|
||||
"std::make_integer_sequence can only be instantiated with an integral type" );
|
||||
static_assert(0 <= _Ep, "std::make_integer_sequence input shall not be negative");
|
||||
typedef __make_integer_sequence_unchecked<_Tp, _Ep> type;
|
||||
};
|
||||
|
||||
} // namespace __detail
|
||||
/** @endcond */
|
||||
|
||||
|
||||
/** C++11 implementation of index sequence
|
||||
* @see https://en.cppreference.com/w/cpp/utility/integer_sequence
|
||||
* @see taken from clang: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/utility?revision=211563&view=markup#l687 */
|
||||
template<class _Tp, _Tp _Np>
|
||||
using make_integer_sequence = typename __detail::__make_integer_sequence<_Tp, _Np>::type;
|
||||
|
||||
/** C++11 implementation of index sequence
|
||||
* @see https://en.cppreference.com/w/cpp/utility/integer_sequence
|
||||
* @see taken from clang: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/utility?revision=211563&view=markup#l687 */
|
||||
template<size_t _Np>
|
||||
using make_index_sequence = make_integer_sequence<size_t, _Np>;
|
||||
|
||||
/** C++11 implementation of index sequence
|
||||
* @see https://en.cppreference.com/w/cpp/utility/integer_sequence
|
||||
* @see taken from clang: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/utility?revision=211563&view=markup#l687 */
|
||||
template<class... _Tp>
|
||||
using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
} // namespace c4
|
||||
|
||||
// NOLINTEND(bugprone-macro-parentheses)
|
||||
|
||||
#endif /* _C4_TYPES_HPP_ */
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
#ifndef C4_UTF_HPP_
|
||||
#define C4_UTF_HPP_
|
||||
|
||||
#include "c4/language.hpp"
|
||||
#include "c4/substr_fwd.hpp"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** @file utf.hpp utilities for UTF and Byte Order Mark */
|
||||
|
||||
namespace c4 {
|
||||
|
||||
/** @defgroup doc_utf UTF utilities
|
||||
* @{ */
|
||||
|
||||
|
||||
/** skip the Byte Order Mark, or get the full string if there is Byte Order Mark.
|
||||
* @see Implements the Byte Order Marks as described in https://en.wikipedia.org/wiki/Byte_order_mark#Byte-order_marks_by_encoding */
|
||||
C4CORE_EXPORT substr skip_bom(substr s);
|
||||
/** skip the Byte Order Mark, or get the full string if there is Byte Order Mark
|
||||
* @see Implements the Byte Order Marks as described in https://en.wikipedia.org/wiki/Byte_order_mark#Byte-order_marks_by_encoding */
|
||||
C4CORE_EXPORT csubstr skip_bom(csubstr s);
|
||||
|
||||
|
||||
/** get the Byte Order Mark, or an empty string if there is no Byte Order Mark
|
||||
* @see Implements the Byte Order Marks as described in https://en.wikipedia.org/wiki/Byte_order_mark#Byte-order_marks_by_encoding */
|
||||
C4CORE_EXPORT substr get_bom(substr s);
|
||||
/** get the Byte Order Mark, or an empty string if there is no Byte Order Mark
|
||||
* @see Implements the Byte Order Marks as described in https://en.wikipedia.org/wiki/Byte_order_mark#Byte-order_marks_by_encoding */
|
||||
C4CORE_EXPORT csubstr get_bom(csubstr s);
|
||||
|
||||
|
||||
/** return the position of the first character not belonging to the
|
||||
* Byte Order Mark, or 0 if there is no Byte Order Mark.
|
||||
* @see Implements the Byte Order Marks as described in https://en.wikipedia.org/wiki/Byte_order_mark#Byte-order_marks_by_encoding */
|
||||
C4CORE_EXPORT size_t first_non_bom(csubstr s);
|
||||
|
||||
|
||||
/** decode the given @p code_point, writing into the output string in
|
||||
* @p out.
|
||||
*
|
||||
* @param out the output string. must have at least 4 bytes (this is
|
||||
* asserted), and must not have a null string.
|
||||
*
|
||||
* @param code_point: must have length in ]0,8], and must not begin
|
||||
* with any of `U+`,`\\x`,`\\u,`\\U`,`0` (asserted)
|
||||
*
|
||||
* @return the part of @p out that was written, which will always be
|
||||
* at most 4 bytes.
|
||||
*/
|
||||
C4CORE_EXPORT substr decode_code_point(substr out, csubstr code_point);
|
||||
|
||||
/** decode the given @p code point, writing into the output string @p
|
||||
* buf, of size @p buflen
|
||||
*
|
||||
* @param buf the output string. must have at least 4 bytes (this is
|
||||
* asserted), and must not be null
|
||||
*
|
||||
* @param buflen the length of the output string. must be at least 4
|
||||
*
|
||||
* @param code: the code point must have length in ]0,8], and must not begin
|
||||
* with any of `U+`,`\\x`,`\\u,`\\U`,`0` (asserted)
|
||||
*
|
||||
* @return the number of written characters, which will always be
|
||||
* at most 4 bytes.
|
||||
*/
|
||||
C4CORE_EXPORT size_t decode_code_point(uint8_t *C4_RESTRICT buf, size_t buflen, uint32_t code);
|
||||
|
||||
/** @} */
|
||||
|
||||
} // namespace c4
|
||||
|
||||
#endif // C4_UTF_HPP_
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
#ifndef _C4_WINDOWS_HPP_
|
||||
#define _C4_WINDOWS_HPP_
|
||||
|
||||
#if defined(_WIN64) || defined(_WIN32)
|
||||
#include "c4/windows_push.hpp"
|
||||
#include <windows.h>
|
||||
#include "c4/windows_pop.hpp"
|
||||
#endif
|
||||
|
||||
#endif /* _C4_WINDOWS_HPP_ */
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
#ifndef _C4_WINDOWS_POP_HPP_
|
||||
#define _C4_WINDOWS_POP_HPP_
|
||||
|
||||
#if defined(_WIN64) || defined(_WIN32)
|
||||
|
||||
#ifdef _c4_AMD64_
|
||||
# undef _c4_AMD64_
|
||||
# undef _AMD64_
|
||||
#endif
|
||||
#ifdef _c4_X86_
|
||||
# undef _c4_X86_
|
||||
# undef _X86_
|
||||
#endif
|
||||
#ifdef _c4_ARM_
|
||||
# undef _c4_ARM_
|
||||
# undef _ARM_
|
||||
#endif
|
||||
|
||||
#ifdef _c4_NOMINMAX
|
||||
# undef _c4_NOMINMAX
|
||||
# undef NOMINMAX
|
||||
#endif
|
||||
|
||||
#ifdef NOGDI
|
||||
# undef _c4_NOGDI
|
||||
# undef NOGDI
|
||||
#endif
|
||||
|
||||
#ifdef VC_EXTRALEAN
|
||||
# undef _c4_VC_EXTRALEAN
|
||||
# undef VC_EXTRALEAN
|
||||
#endif
|
||||
|
||||
#ifdef WIN32_LEAN_AND_MEAN
|
||||
# undef _c4_WIN32_LEAN_AND_MEAN
|
||||
# undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#endif /* defined(_WIN64) || defined(_WIN32) */
|
||||
|
||||
#endif /* _C4_WINDOWS_POP_HPP_ */
|
||||
-102
@@ -1,102 +0,0 @@
|
||||
#ifndef _C4_WINDOWS_PUSH_HPP_
|
||||
#define _C4_WINDOWS_PUSH_HPP_
|
||||
|
||||
/** @file windows_push.hpp sets up macros to include windows header files
|
||||
* without pulling in all of <windows.h>
|
||||
*
|
||||
* @see #include windows_pop.hpp to undefine these macros
|
||||
*
|
||||
* @see https://aras-p.info/blog/2018/01/12/Minimizing-windows.h/ */
|
||||
|
||||
|
||||
#if defined(_WIN64) || defined(_WIN32)
|
||||
|
||||
#if defined(_M_AMD64)
|
||||
# ifndef _AMD64_
|
||||
# define _c4_AMD64_
|
||||
# define _AMD64_
|
||||
# endif
|
||||
#elif defined(_M_IX86)
|
||||
# ifndef _X86_
|
||||
# define _c4_X86_
|
||||
# define _X86_
|
||||
# endif
|
||||
#elif defined(_M_ARM64)
|
||||
# ifndef _ARM64_
|
||||
# define _c4_ARM64_
|
||||
# define _ARM64_
|
||||
# endif
|
||||
#elif defined(_M_ARM)
|
||||
# ifndef _ARM_
|
||||
# define _c4_ARM_
|
||||
# define _ARM_
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef NOMINMAX
|
||||
# define _c4_NOMINMAX
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
|
||||
#ifndef NOGDI
|
||||
# define _c4_NOGDI
|
||||
# define NOGDI
|
||||
#endif
|
||||
|
||||
#ifndef VC_EXTRALEAN
|
||||
# define _c4_VC_EXTRALEAN
|
||||
# define VC_EXTRALEAN
|
||||
#endif
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
# define _c4_WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
/* If defined, the following flags inhibit definition
|
||||
* of the indicated items.
|
||||
*
|
||||
* NOGDICAPMASKS - CC_*, LC_*, PC_*, CP_*, TC_*, RC_
|
||||
* NOVIRTUALKEYCODES - VK_*
|
||||
* NOWINMESSAGES - WM_*, EM_*, LB_*, CB_*
|
||||
* NOWINSTYLES - WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_*
|
||||
* NOSYSMETRICS - SM_*
|
||||
* NOMENUS - MF_*
|
||||
* NOICONS - IDI_*
|
||||
* NOKEYSTATES - MK_*
|
||||
* NOSYSCOMMANDS - SC_*
|
||||
* NORASTEROPS - Binary and Tertiary raster ops
|
||||
* NOSHOWWINDOW - SW_*
|
||||
* OEMRESOURCE - OEM Resource values
|
||||
* NOATOM - Atom Manager routines
|
||||
* NOCLIPBOARD - Clipboard routines
|
||||
* NOCOLOR - Screen colors
|
||||
* NOCTLMGR - Control and Dialog routines
|
||||
* NODRAWTEXT - DrawText() and DT_*
|
||||
* NOGDI - All GDI defines and routines
|
||||
* NOKERNEL - All KERNEL defines and routines
|
||||
* NOUSER - All USER defines and routines
|
||||
* NONLS - All NLS defines and routines
|
||||
* NOMB - MB_* and MessageBox()
|
||||
* NOMEMMGR - GMEM_*, LMEM_*, GHND, LHND, associated routines
|
||||
* NOMETAFILE - typedef METAFILEPICT
|
||||
* NOMINMAX - Macros min(a,b) and max(a,b)
|
||||
* NOMSG - typedef MSG and associated routines
|
||||
* NOOPENFILE - OpenFile(), OemToAnsi, AnsiToOem, and OF_*
|
||||
* NOSCROLL - SB_* and scrolling routines
|
||||
* NOSERVICE - All Service Controller routines, SERVICE_ equates, etc.
|
||||
* NOSOUND - Sound driver routines
|
||||
* NOTEXTMETRIC - typedef TEXTMETRIC and associated routines
|
||||
* NOWH - SetWindowsHook and WH_*
|
||||
* NOWINOFFSETS - GWL_*, GCL_*, associated routines
|
||||
* NOCOMM - COMM driver routines
|
||||
* NOKANJI - Kanji support stuff.
|
||||
* NOHELP - Help engine interface.
|
||||
* NOPROFILER - Profiler interface.
|
||||
* NODEFERWINDOWPOS - DeferWindowPos routines
|
||||
* NOMCX - Modem Configuration Extensions
|
||||
*/
|
||||
|
||||
#endif /* defined(_WIN64) || defined(_WIN32) */
|
||||
|
||||
#endif /* _C4_WINDOWS_PUSH_HPP_ */
|
||||
-660
@@ -1,660 +0,0 @@
|
||||
#ifndef _C4_YML_COMMON_HPP_
|
||||
#define _C4_YML_COMMON_HPP_
|
||||
|
||||
/** @file common.hpp Common utilities and infrastructure used by ryml. */
|
||||
|
||||
#include <cstddef>
|
||||
#include <c4/substr.hpp>
|
||||
#include <c4/charconv.hpp>
|
||||
#include <c4/dump.hpp>
|
||||
#include <c4/yml/export.hpp>
|
||||
|
||||
#if defined(C4_MSVC) || defined(C4_MINGW) || defined(_WIN32) || defined(C4_WIN)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef RYML_ERRMSG_SIZE
|
||||
/// size for the error message buffer
|
||||
#define RYML_ERRMSG_SIZE (1024)
|
||||
#endif
|
||||
|
||||
#ifndef RYML_LOGBUF_SIZE
|
||||
/// size for the buffer used to format individual values to string
|
||||
/// while preparing an error message. This is only used for formatting
|
||||
/// individual values in the message; final messages will be larger
|
||||
/// than this value (see @ref RYML_ERRMSG_SIZE). This is also used for
|
||||
/// the detailed debug log messages when RYML_DBG is defined.
|
||||
#define RYML_LOGBUF_SIZE (256)
|
||||
#endif
|
||||
|
||||
#ifndef RYML_LOGBUF_SIZE_MAX
|
||||
/// size for the fallback larger log buffer. When @ref
|
||||
/// RYML_LOGBUF_SIZE is not large enough to convert a value to string,
|
||||
/// then temporary stack memory is allocated up to
|
||||
/// RYML_LOGBUF_SIZE_MAX. This limit is in place to prevent a stack
|
||||
/// overflow. If the printed value requires more than
|
||||
/// RYML_LOGBUF_SIZE_MAX, the value is silently skipped.
|
||||
#define RYML_LOGBUF_SIZE_MAX (1024)
|
||||
#endif
|
||||
|
||||
#ifndef RYML_LOCATIONS_SMALL_THRESHOLD
|
||||
/// threshold at which a location search will revert from linear to
|
||||
/// binary search.
|
||||
#define RYML_LOCATIONS_SMALL_THRESHOLD (30)
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Specify groups to have a predefined topic order in doxygen:
|
||||
|
||||
/** @defgroup doc_quickstart Quickstart
|
||||
*
|
||||
* Example code for every feature.
|
||||
*/
|
||||
|
||||
/** @defgroup doc_parse Parse utilities
|
||||
* @see sample::sample_parse_in_place
|
||||
* @see sample::sample_parse_in_arena
|
||||
* @see sample::sample_parse_file
|
||||
* @see sample::sample_parse_reuse_tree
|
||||
* @see sample::sample_parse_reuse_parser
|
||||
* @see sample::sample_parse_reuse_tree_and_parser
|
||||
* @see sample::sample_location_tracking
|
||||
*/
|
||||
|
||||
/** @defgroup doc_emit Emit utilities
|
||||
*
|
||||
* Utilities to emit YAML and JSON, either to a memory buffer or to a
|
||||
* file or ostream-like class.
|
||||
*
|
||||
* @see sample::sample_emit_to_container
|
||||
* @see sample::sample_emit_to_stream
|
||||
* @see sample::sample_emit_to_file
|
||||
* @see sample::sample_emit_nested_node
|
||||
* @see sample::sample_emit_style
|
||||
*/
|
||||
|
||||
/** @defgroup doc_node_type Node types
|
||||
*/
|
||||
|
||||
/** @defgroup doc_tree Tree utilities
|
||||
* @see sample::sample_quick_overview
|
||||
* @see sample::sample_iterate_trees
|
||||
* @see sample::sample_create_trees
|
||||
* @see sample::sample_tree_arena
|
||||
*
|
||||
* @see sample::sample_static_trees
|
||||
* @see sample::sample_location_tracking
|
||||
*
|
||||
* @see sample::sample_docs
|
||||
* @see sample::sample_anchors_and_aliases
|
||||
* @see sample::sample_tags
|
||||
*/
|
||||
|
||||
/** @defgroup doc_node_classes Node classes
|
||||
*
|
||||
* High-level node classes.
|
||||
*
|
||||
* @see sample::sample_quick_overview
|
||||
* @see sample::sample_iterate_trees
|
||||
* @see sample::sample_create_trees
|
||||
* @see sample::sample_tree_arena
|
||||
*/
|
||||
|
||||
/** @defgroup doc_callbacks Callbacks for errors and allocation
|
||||
*
|
||||
* Functions called by ryml to allocate/free memory and to report
|
||||
* errors.
|
||||
*
|
||||
* @see sample::sample_error_handler
|
||||
* @see sample::sample_global_allocator
|
||||
* @see sample::sample_per_tree_allocator
|
||||
*/
|
||||
|
||||
/** @defgroup doc_serialization Serialization/deserialization
|
||||
*
|
||||
* Contains information on how to serialize and deserialize
|
||||
* fundamental types, user scalar types, user container types and
|
||||
* interop with std scalar/container types.
|
||||
*
|
||||
*/
|
||||
|
||||
/** @defgroup doc_ref_utils Anchor/Reference utilities
|
||||
*
|
||||
* @see sample::sample_anchors_and_aliases
|
||||
* */
|
||||
|
||||
/** @defgroup doc_tag_utils Tag utilities
|
||||
* @see sample::sample_tags
|
||||
*/
|
||||
|
||||
/** @defgroup doc_preprocessors Preprocessors
|
||||
*
|
||||
* Functions for preprocessing YAML prior to parsing.
|
||||
*/
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// document macros for doxygen
|
||||
#ifdef __DOXYGEN__ // defined in Doxyfile::PREDEFINED
|
||||
|
||||
/** define this macro with a boolean value to enable/disable
|
||||
* assertions to check preconditions and assumptions throughout the
|
||||
* codebase; this causes a slowdown of the code, and larger code
|
||||
* size. By default, this macro is defined unless NDEBUG is defined
|
||||
* (see C4_USE_ASSERT); as a result, by default this macro is truthy
|
||||
* only in debug builds. */
|
||||
# define RYML_USE_ASSERT
|
||||
|
||||
/** (Undefined by default) Define this macro to disable ryml's default
|
||||
* implementation of the callback functions; see @ref c4::yml::Callbacks */
|
||||
# define RYML_NO_DEFAULT_CALLBACKS
|
||||
|
||||
/** (Undefined by default) When this macro is defined (and
|
||||
* @ref RYML_NO_DEFAULT_CALLBACKS is not defined), the default error
|
||||
* handler will throw C++ exceptions of type `std::runtime_error`. */
|
||||
# define RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS
|
||||
|
||||
/** Conditionally expands to `noexcept` when @ref RYML_USE_ASSERT is 0 and
|
||||
* is empty otherwise. The user is unable to override this macro. */
|
||||
# define RYML_NOEXCEPT
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
/** @cond dev*/
|
||||
#ifndef RYML_USE_ASSERT
|
||||
# define RYML_USE_ASSERT C4_USE_ASSERT
|
||||
#endif
|
||||
|
||||
#if RYML_USE_ASSERT
|
||||
# define RYML_ASSERT(cond) RYML_CHECK(cond)
|
||||
# define RYML_ASSERT_MSG(cond, msg) RYML_CHECK_MSG(cond, msg)
|
||||
# define _RYML_CB_ASSERT(cb, cond) _RYML_CB_CHECK((cb), (cond))
|
||||
# define _RYML_CB_ASSERT_(cb, cond, loc) _RYML_CB_CHECK((cb), (cond), (loc))
|
||||
# define RYML_NOEXCEPT
|
||||
#else
|
||||
# define RYML_ASSERT(cond)
|
||||
# define RYML_ASSERT_MSG(cond, msg)
|
||||
# define _RYML_CB_ASSERT(cb, cond)
|
||||
# define _RYML_CB_ASSERT_(cb, cond, loc)
|
||||
# define RYML_NOEXCEPT noexcept
|
||||
#endif
|
||||
|
||||
#define RYML_DEPRECATED(msg) C4_DEPRECATED(msg)
|
||||
|
||||
#define RYML_CHECK(cond) \
|
||||
do { \
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
c4::yml::error("check failed: " #cond, c4::yml::Location(__FILE__, __LINE__, 0)); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define RYML_CHECK_MSG(cond, msg) \
|
||||
do \
|
||||
{ \
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
c4::yml::error(msg ": check failed: " #cond, c4::yml::Location(__FILE__, __LINE__, 0)); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#if defined(RYML_DBG) && !defined(NDEBUG) && !defined(C4_NO_DEBUG_BREAK)
|
||||
# define RYML_DEBUG_BREAK() \
|
||||
do { \
|
||||
if(c4::get_error_flags() & c4::ON_ERROR_DEBUGBREAK) \
|
||||
{ \
|
||||
C4_DEBUG_BREAK(); \
|
||||
} \
|
||||
} while(0)
|
||||
#else
|
||||
# define RYML_DEBUG_BREAK()
|
||||
#endif
|
||||
|
||||
/** @endcond */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace c4 {
|
||||
namespace yml {
|
||||
|
||||
C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wold-style-cast")
|
||||
|
||||
|
||||
#ifndef RYML_ID_TYPE
|
||||
/** The type of a node id in the YAML tree. In the future, the default
|
||||
* will likely change to int32_t, which was observed to be faster.
|
||||
* @see id_type */
|
||||
#define RYML_ID_TYPE size_t
|
||||
#endif
|
||||
|
||||
|
||||
/** The type of a node id in the YAML tree; to override the default
|
||||
* type, define the macro @ref RYML_ID_TYPE to a suitable integer
|
||||
* type. */
|
||||
using id_type = RYML_ID_TYPE;
|
||||
static_assert(std::is_integral<id_type>::value, "id_type must be an integer type");
|
||||
|
||||
|
||||
C4_SUPPRESS_WARNING_GCC_WITH_PUSH("-Wuseless-cast")
|
||||
enum : id_type {
|
||||
/** an index to none */
|
||||
NONE = id_type(-1),
|
||||
};
|
||||
C4_SUPPRESS_WARNING_GCC_CLANG_POP
|
||||
|
||||
|
||||
enum : size_t {
|
||||
/** a null string position */
|
||||
npos = size_t(-1)
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//! holds a position into a source buffer
|
||||
struct RYML_EXPORT LineCol
|
||||
{
|
||||
//! number of bytes from the beginning of the source buffer
|
||||
size_t offset;
|
||||
//! line
|
||||
size_t line;
|
||||
//! column
|
||||
size_t col;
|
||||
|
||||
LineCol() = default;
|
||||
//! construct from line and column
|
||||
LineCol(size_t l, size_t c) : offset(0), line(l), col(c) {}
|
||||
//! construct from offset, line and column
|
||||
LineCol(size_t o, size_t l, size_t c) : offset(o), line(l), col(c) {}
|
||||
};
|
||||
static_assert(std::is_trivially_copyable<LineCol>::value, "LineCol not trivially copyable");
|
||||
static_assert(std::is_trivially_default_constructible<LineCol>::value, "LineCol not trivially default constructible");
|
||||
static_assert(std::is_standard_layout<LineCol>::value, "Location not trivial");
|
||||
|
||||
|
||||
//! a source file position
|
||||
struct RYML_EXPORT Location
|
||||
{
|
||||
//! number of bytes from the beginning of the source buffer
|
||||
size_t offset;
|
||||
//! line
|
||||
size_t line;
|
||||
//! column
|
||||
size_t col;
|
||||
//! file name
|
||||
csubstr name;
|
||||
|
||||
operator bool () const { return !name.empty() || line != 0 || offset != 0 || col != 0; }
|
||||
operator LineCol const& () const { return reinterpret_cast<LineCol const&>(*this); } // NOLINT
|
||||
|
||||
Location() = default;
|
||||
Location( size_t l, size_t c) : offset( ), line(l), col(c), name( ) {}
|
||||
Location( size_t b, size_t l, size_t c) : offset(b), line(l), col(c), name( ) {}
|
||||
Location( csubstr n, size_t l, size_t c) : offset( ), line(l), col(c), name(n) {}
|
||||
Location( csubstr n, size_t b, size_t l, size_t c) : offset(b), line(l), col(c), name(n) {}
|
||||
Location(const char *n, size_t l, size_t c) : offset( ), line(l), col(c), name(to_csubstr(n)) {}
|
||||
Location(const char *n, size_t b, size_t l, size_t c) : offset(b), line(l), col(c), name(to_csubstr(n)) {}
|
||||
};
|
||||
static_assert(std::is_standard_layout<Location>::value, "Location not trivial");
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** @addtogroup doc_callbacks
|
||||
*
|
||||
* @{ */
|
||||
|
||||
struct Callbacks;
|
||||
|
||||
|
||||
/** set the global callbacks for the library; after a call to this
|
||||
* function, these callbacks will be used by newly created objects
|
||||
* (unless they are copying older objects with different
|
||||
* callbacks). If @ref RYML_NO_DEFAULT_CALLBACKS is defined, it is
|
||||
* mandatory to call this function prior to using any other library
|
||||
* facility.
|
||||
*
|
||||
* @warning This function is NOT thread-safe.
|
||||
*
|
||||
* @warning the error callback must never return: see @ref pfn_error
|
||||
* for more details */
|
||||
RYML_EXPORT void set_callbacks(Callbacks const& c);
|
||||
|
||||
/** get the global callbacks
|
||||
* @warning This function is not thread-safe. */
|
||||
RYML_EXPORT Callbacks const& get_callbacks();
|
||||
|
||||
/** set the global callbacks back to their defaults ()
|
||||
* @warning This function is not thread-safe. */
|
||||
RYML_EXPORT void reset_callbacks();
|
||||
|
||||
|
||||
/** the type of the function used to report errors
|
||||
*
|
||||
* @warning When given by the user, this function MUST interrupt
|
||||
* execution, typically by either throwing an exception, or using
|
||||
* `std::longjmp()` ([see
|
||||
* documentation](https://en.cppreference.com/w/cpp/utility/program/setjmp))
|
||||
* or by calling `std::abort()`. If the function returned, the parser
|
||||
* would enter into an infinite loop, or the program may crash. */
|
||||
using pfn_error = void (*) (const char* msg, size_t msg_len, Location location, void *user_data);
|
||||
|
||||
|
||||
/** the type of the function used to allocate memory; ryml will only
|
||||
* allocate memory through this callback. */
|
||||
using pfn_allocate = void* (*)(size_t len, void* hint, void *user_data);
|
||||
|
||||
|
||||
/** the type of the function used to free memory; ryml will only free
|
||||
* memory through this callback. */
|
||||
using pfn_free = void (*)(void* mem, size_t size, void *user_data);
|
||||
|
||||
|
||||
/** a c-style callbacks class. Can be used globally by the library
|
||||
* and/or locally by @ref Tree and @ref Parser objects. */
|
||||
struct RYML_EXPORT Callbacks
|
||||
{
|
||||
void * m_user_data;
|
||||
pfn_allocate m_allocate;
|
||||
pfn_free m_free;
|
||||
pfn_error m_error;
|
||||
|
||||
/** Construct an object with the default callbacks. If
|
||||
* @ref RYML_NO_DEFAULT_CALLBACKS is defined, the object will have null
|
||||
* members.*/
|
||||
Callbacks() noexcept;
|
||||
|
||||
/** Construct an object with the given callbacks.
|
||||
*
|
||||
* @param user_data Data to be forwarded in every call to a callback.
|
||||
*
|
||||
* @param alloc A pointer to an allocate function. Unless
|
||||
* @ref RYML_NO_DEFAULT_CALLBACKS is defined, when this
|
||||
* parameter is null, will fall back to ryml's default
|
||||
* alloc implementation.
|
||||
*
|
||||
* @param free A pointer to a free function. Unless
|
||||
* @ref RYML_NO_DEFAULT_CALLBACKS is defined, when this
|
||||
* parameter is null, will fall back to ryml's default free
|
||||
* implementation.
|
||||
*
|
||||
* @param error A pointer to an error function, which must never
|
||||
* return (see @ref pfn_error). Unless
|
||||
* @ref RYML_NO_DEFAULT_CALLBACKS is defined, when this
|
||||
* parameter is null, will fall back to ryml's default
|
||||
* error implementation.
|
||||
*/
|
||||
Callbacks(void *user_data, pfn_allocate alloc, pfn_free free, pfn_error error);
|
||||
|
||||
bool operator!= (Callbacks const& that) const { return !operator==(that); }
|
||||
bool operator== (Callbacks const& that) const
|
||||
{
|
||||
return (m_user_data == that.m_user_data &&
|
||||
m_allocate == that.m_allocate &&
|
||||
m_free == that.m_free &&
|
||||
m_error == that.m_error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
typedef enum {
|
||||
NOBOM,
|
||||
UTF8,
|
||||
UTF16LE,
|
||||
UTF16BE,
|
||||
UTF32LE,
|
||||
UTF32BE,
|
||||
} Encoding_e;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// @cond dev
|
||||
|
||||
// BEWARE! MSVC requires that [[noreturn]] appears before RYML_EXPORT
|
||||
[[noreturn]] RYML_EXPORT void error(Callbacks const& cb, const char *msg, size_t msg_len, Location loc);
|
||||
[[noreturn]] RYML_EXPORT void error(const char *msg, size_t msg_len, Location loc);
|
||||
|
||||
[[noreturn]] inline void error(const char *msg, size_t msg_len)
|
||||
{
|
||||
error(msg, msg_len, Location{});
|
||||
}
|
||||
template<size_t N>
|
||||
[[noreturn]] inline void error(const char (&msg)[N], Location loc)
|
||||
{
|
||||
error(msg, N-1, loc);
|
||||
}
|
||||
template<size_t N>
|
||||
[[noreturn]] inline void error(const char (&msg)[N])
|
||||
{
|
||||
error(msg, N-1, Location{});
|
||||
}
|
||||
|
||||
#define _RYML_CB_ERR(cb, msg_literal) \
|
||||
_RYML_CB_ERR_(cb, msg_literal, c4::yml::Location(__FILE__, 0, __LINE__, 0))
|
||||
#define _RYML_CB_CHECK(cb, cond) \
|
||||
_RYML_CB_CHECK_(cb, cond, c4::yml::Location(__FILE__, 0, __LINE__, 0))
|
||||
#define _RYML_CB_ERR_(cb, msg_literal, loc) \
|
||||
do \
|
||||
{ \
|
||||
const char msg[] = msg_literal; \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
c4::yml::error((cb), msg, sizeof(msg)-1, loc); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} while(0)
|
||||
#define _RYML_CB_CHECK_(cb, cond, loc) \
|
||||
do \
|
||||
{ \
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
const char msg[] = "check failed: " #cond; \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
c4::yml::error((cb), msg, sizeof(msg)-1, loc); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} \
|
||||
} while(0)
|
||||
#define _RYML_CB_ALLOC_HINT(cb, T, num, hint) (T*) (cb).m_allocate((num) * sizeof(T), (hint), (cb).m_user_data)
|
||||
#define _RYML_CB_ALLOC(cb, T, num) _RYML_CB_ALLOC_HINT((cb), T, (num), nullptr)
|
||||
#define _RYML_CB_FREE(cb, buf, T, num) \
|
||||
do { \
|
||||
(cb).m_free((buf), (num) * sizeof(T), (cb).m_user_data); \
|
||||
(buf) = nullptr; \
|
||||
} while(0)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
typedef enum {
|
||||
BLOCK_LITERAL, //!< keep newlines (|)
|
||||
BLOCK_FOLD //!< replace newline with single space (>)
|
||||
} BlockStyle_e;
|
||||
|
||||
typedef enum {
|
||||
CHOMP_CLIP, //!< single newline at end (default)
|
||||
CHOMP_STRIP, //!< no newline at end (-)
|
||||
CHOMP_KEEP //!< all newlines from end (+)
|
||||
} BlockChomp_e;
|
||||
|
||||
|
||||
/** Abstracts the fact that a scalar filter result may not fit in the
|
||||
* intended memory. */
|
||||
struct FilterResult
|
||||
{
|
||||
C4_ALWAYS_INLINE bool valid() const noexcept { return str.str != nullptr; }
|
||||
C4_ALWAYS_INLINE size_t required_len() const noexcept { return str.len; }
|
||||
C4_ALWAYS_INLINE csubstr get() const { RYML_ASSERT(valid()); return str; }
|
||||
csubstr str;
|
||||
};
|
||||
/** Abstracts the fact that a scalar filter result may not fit in the
|
||||
* intended memory. */
|
||||
struct FilterResultExtending
|
||||
{
|
||||
C4_ALWAYS_INLINE bool valid() const noexcept { return str.str != nullptr; }
|
||||
C4_ALWAYS_INLINE size_t required_len() const noexcept { return reqlen; }
|
||||
C4_ALWAYS_INLINE csubstr get() const { RYML_ASSERT(valid()); return str; }
|
||||
csubstr str;
|
||||
size_t reqlen;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace detail {
|
||||
// is there a better way to do this?
|
||||
template<int8_t signedval, uint8_t unsignedval>
|
||||
struct _charconstant_t
|
||||
: public std::conditional<std::is_signed<char>::value,
|
||||
std::integral_constant<int8_t, static_cast<int8_t>(unsignedval)>,
|
||||
std::integral_constant<uint8_t, unsignedval>>::type
|
||||
{};
|
||||
#define _RYML_CHCONST(signedval, unsignedval) ::c4::yml::detail::_charconstant_t<INT8_C(signedval), UINT8_C(unsignedval)>::value
|
||||
} // namespace detail
|
||||
|
||||
|
||||
namespace detail {
|
||||
struct _SubstrWriter
|
||||
{
|
||||
substr buf;
|
||||
size_t pos;
|
||||
_SubstrWriter(substr buf_, size_t pos_=0) : buf(buf_), pos(pos_) { C4_ASSERT(buf.str); }
|
||||
void append(csubstr s)
|
||||
{
|
||||
C4_ASSERT(!s.overlaps(buf));
|
||||
C4_ASSERT(s.str || !s.len);
|
||||
if(s.len && pos + s.len <= buf.len)
|
||||
{
|
||||
C4_ASSERT(s.str);
|
||||
memcpy(buf.str + pos, s.str, s.len);
|
||||
}
|
||||
pos += s.len;
|
||||
}
|
||||
void append(char c)
|
||||
{
|
||||
C4_ASSERT(buf.str);
|
||||
if(pos < buf.len)
|
||||
buf.str[pos] = c;
|
||||
++pos;
|
||||
}
|
||||
void append_n(char c, size_t numtimes)
|
||||
{
|
||||
C4_ASSERT(buf.str);
|
||||
if(numtimes && pos + numtimes < buf.len)
|
||||
memset(buf.str + pos, c, numtimes);
|
||||
pos += numtimes;
|
||||
}
|
||||
size_t slack() const { return pos <= buf.len ? buf.len - pos : 0; }
|
||||
size_t excess() const { return pos > buf.len ? pos - buf.len : 0; }
|
||||
//! get the part written so far
|
||||
csubstr curr() const { return pos <= buf.len ? buf.first(pos) : buf; }
|
||||
//! get the part that is still free to write to (the remainder)
|
||||
substr rem() const { return pos < buf.len ? buf.sub(pos) : buf.last(0); }
|
||||
|
||||
size_t advance(size_t more) { pos += more; return pos; }
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
|
||||
namespace detail {
|
||||
// dumpfn is a function abstracting prints to terminal (or to string).
|
||||
template<class DumpFn, class ...Args>
|
||||
C4_NO_INLINE void _dump(DumpFn &&dumpfn, csubstr fmt, Args&& ...args)
|
||||
{
|
||||
DumpResults results;
|
||||
// try writing everything:
|
||||
{
|
||||
// buffer for converting individual arguments. it is defined
|
||||
// in a child scope to free it in case the buffer is too small
|
||||
// for any of the arguments.
|
||||
char writebuf[RYML_LOGBUF_SIZE];
|
||||
results = format_dump_resume(std::forward<DumpFn>(dumpfn), writebuf, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
// if any of the arguments failed to fit the buffer, allocate a
|
||||
// larger buffer (up to a limit) and resume writing.
|
||||
//
|
||||
// results.bufsize is set to the size of the largest element
|
||||
// serialized. Eg int(1) will require 1 byte.
|
||||
if(C4_UNLIKELY(results.bufsize > RYML_LOGBUF_SIZE))
|
||||
{
|
||||
const size_t bufsize = results.bufsize <= RYML_LOGBUF_SIZE_MAX ? results.bufsize : RYML_LOGBUF_SIZE_MAX;
|
||||
#ifdef C4_MSVC
|
||||
substr largerbuf = {static_cast<char*>(_alloca(bufsize)), bufsize};
|
||||
#else
|
||||
substr largerbuf = {static_cast<char*>(alloca(bufsize)), bufsize};
|
||||
#endif
|
||||
results = format_dump_resume(std::forward<DumpFn>(dumpfn), results, largerbuf, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
template<class ...Args>
|
||||
C4_NORETURN C4_NO_INLINE void _report_err(Callbacks const& C4_RESTRICT callbacks, csubstr fmt, Args const& C4_RESTRICT ...args)
|
||||
{
|
||||
char errmsg[RYML_ERRMSG_SIZE] = {0};
|
||||
detail::_SubstrWriter writer(errmsg);
|
||||
auto dumpfn = [&writer](csubstr s){ writer.append(s); };
|
||||
_dump(dumpfn, fmt, args...);
|
||||
writer.append('\n');
|
||||
const size_t len = writer.pos < RYML_ERRMSG_SIZE ? writer.pos : RYML_ERRMSG_SIZE;
|
||||
callbacks.m_error(errmsg, len, {}, callbacks.m_user_data);
|
||||
C4_UNREACHABLE_AFTER_ERR();
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
|
||||
inline csubstr _c4prc(const char &C4_RESTRICT c) // pass by reference!
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case '\n': return csubstr("\\n");
|
||||
case '\t': return csubstr("\\t");
|
||||
case '\0': return csubstr("\\0");
|
||||
case '\r': return csubstr("\\r");
|
||||
case '\f': return csubstr("\\f");
|
||||
case '\b': return csubstr("\\b");
|
||||
case '\v': return csubstr("\\v");
|
||||
case '\a': return csubstr("\\a");
|
||||
default: return csubstr(&c, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
|
||||
C4_SUPPRESS_WARNING_GCC_POP
|
||||
|
||||
} // namespace yml
|
||||
} // namespace c4
|
||||
|
||||
#endif /* _C4_YML_COMMON_HPP_ */
|
||||
-200
@@ -1,200 +0,0 @@
|
||||
#ifndef C4_YML_DETAIL_CHECKS_HPP_
|
||||
#define C4_YML_DETAIL_CHECKS_HPP_
|
||||
|
||||
#include "c4/yml/tree.hpp"
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
#elif defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wtype-limits" // error: comparison of unsigned expression >= 0 is always true
|
||||
#elif defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4296/*expression is always 'boolean_value'*/)
|
||||
#endif
|
||||
|
||||
namespace c4 {
|
||||
namespace yml {
|
||||
|
||||
|
||||
void check_invariants(Tree const& t, id_type node=NONE);
|
||||
void check_free_list(Tree const& t);
|
||||
void check_arena(Tree const& t);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline void check_invariants(Tree const& t, id_type node)
|
||||
{
|
||||
if(node == NONE)
|
||||
{
|
||||
if(t.empty()) return;
|
||||
node = t.root_id();
|
||||
}
|
||||
|
||||
NodeData const& n = *t._p(node);
|
||||
#if defined(RYML_DBG) && 0
|
||||
if(n.m_first_child != NONE || n.m_last_child != NONE)
|
||||
{
|
||||
printf("check(%zu): fc=%zu lc=%zu\n", node, n.m_first_child, n.m_last_child);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("check(%zu)\n", node);
|
||||
}
|
||||
#endif
|
||||
|
||||
C4_CHECK(n.m_parent != node);
|
||||
if(n.m_parent == NONE)
|
||||
{
|
||||
C4_CHECK(t.is_root(node));
|
||||
}
|
||||
else //if(n.m_parent != NONE)
|
||||
{
|
||||
C4_CHECK(t.has_child(n.m_parent, node));
|
||||
|
||||
auto const& p = *t._p(n.m_parent);
|
||||
if(n.m_prev_sibling == NONE)
|
||||
{
|
||||
C4_CHECK(p.m_first_child == node);
|
||||
C4_CHECK(t.first_sibling(node) == node);
|
||||
}
|
||||
else
|
||||
{
|
||||
C4_CHECK(p.m_first_child != node);
|
||||
C4_CHECK(t.first_sibling(node) != node);
|
||||
}
|
||||
|
||||
if(n.m_next_sibling == NONE)
|
||||
{
|
||||
C4_CHECK(p.m_last_child == node);
|
||||
C4_CHECK(t.last_sibling(node) == node);
|
||||
}
|
||||
else
|
||||
{
|
||||
C4_CHECK(p.m_last_child != node);
|
||||
C4_CHECK(t.last_sibling(node) != node);
|
||||
}
|
||||
}
|
||||
|
||||
C4_CHECK(n.m_first_child != node);
|
||||
C4_CHECK(n.m_last_child != node);
|
||||
if(n.m_first_child != NONE || n.m_last_child != NONE)
|
||||
{
|
||||
C4_CHECK(n.m_first_child != NONE);
|
||||
C4_CHECK(n.m_last_child != NONE);
|
||||
}
|
||||
|
||||
C4_CHECK(n.m_prev_sibling != node);
|
||||
C4_CHECK(n.m_next_sibling != node);
|
||||
if(n.m_prev_sibling != NONE)
|
||||
{
|
||||
C4_CHECK(t._p(n.m_prev_sibling)->m_next_sibling == node);
|
||||
C4_CHECK(t._p(n.m_prev_sibling)->m_prev_sibling != node);
|
||||
}
|
||||
if(n.m_next_sibling != NONE)
|
||||
{
|
||||
C4_CHECK(t._p(n.m_next_sibling)->m_prev_sibling == node);
|
||||
C4_CHECK(t._p(n.m_next_sibling)->m_next_sibling != node);
|
||||
}
|
||||
|
||||
id_type count = 0;
|
||||
for(id_type i = n.m_first_child; i != NONE; i = t.next_sibling(i))
|
||||
{
|
||||
#if defined(RYML_DBG) && 0
|
||||
printf("check(%zu): descend to child[%zu]=%zu\n", node, count, i);
|
||||
#endif
|
||||
auto const& ch = *t._p(i);
|
||||
C4_CHECK(ch.m_parent == node);
|
||||
C4_CHECK(ch.m_next_sibling != i);
|
||||
++count;
|
||||
}
|
||||
C4_CHECK(count == t.num_children(node));
|
||||
|
||||
if(n.m_prev_sibling == NONE && n.m_next_sibling == NONE)
|
||||
{
|
||||
if(n.m_parent != NONE)
|
||||
{
|
||||
C4_CHECK(t.num_children(n.m_parent) == 1);
|
||||
C4_CHECK(t.num_siblings(node) == 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(node == t.root_id())
|
||||
{
|
||||
C4_CHECK(t.size() == t.m_size);
|
||||
C4_CHECK(t.capacity() == t.m_cap);
|
||||
C4_CHECK(t.m_cap == t.m_size + t.slack());
|
||||
check_free_list(t);
|
||||
check_arena(t);
|
||||
}
|
||||
|
||||
for(id_type i = t.first_child(node); i != NONE; i = t.next_sibling(i))
|
||||
{
|
||||
check_invariants(t, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline void check_free_list(Tree const& t)
|
||||
{
|
||||
if(t.m_free_head == NONE)
|
||||
{
|
||||
C4_CHECK(t.m_free_tail == t.m_free_head);
|
||||
return;
|
||||
}
|
||||
|
||||
C4_CHECK(t.m_free_head >= 0 && t.m_free_head < t.m_cap);
|
||||
C4_CHECK(t.m_free_tail >= 0 && t.m_free_tail < t.m_cap);
|
||||
|
||||
auto const& head = *t._p(t.m_free_head);
|
||||
//auto const& tail = *t._p(t.m_free_tail);
|
||||
|
||||
//C4_CHECK(head.m_prev_sibling == NONE);
|
||||
//C4_CHECK(tail.m_next_sibling == NONE);
|
||||
|
||||
id_type count = 0;
|
||||
for(id_type i = t.m_free_head, prev = NONE; i != NONE; i = t._p(i)->m_next_sibling)
|
||||
{
|
||||
auto const& elm = *t._p(i);
|
||||
if(&elm != &head)
|
||||
{
|
||||
C4_CHECK(elm.m_prev_sibling == prev);
|
||||
}
|
||||
prev = i;
|
||||
++count;
|
||||
}
|
||||
C4_CHECK(count == t.slack());
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline void check_arena(Tree const& t)
|
||||
{
|
||||
C4_CHECK(t.m_arena.len == 0 || (t.m_arena_pos >= 0 && t.m_arena_pos <= t.m_arena.len));
|
||||
C4_CHECK(t.arena_size() == t.m_arena_pos);
|
||||
C4_CHECK(t.arena_slack() + t.m_arena_pos == t.m_arena.len);
|
||||
}
|
||||
|
||||
|
||||
} /* namespace yml */
|
||||
} /* namespace c4 */
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
# pragma GCC diagnostic pop
|
||||
#elif defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif /* C4_YML_DETAIL_CHECKS_HPP_ */
|
||||
@@ -1,129 +0,0 @@
|
||||
#ifndef _C4_YML_DETAIL_DBGPRINT_HPP_
|
||||
#define _C4_YML_DETAIL_DBGPRINT_HPP_
|
||||
|
||||
#ifndef _C4_YML_COMMON_HPP_
|
||||
#include "../common.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef RYML_DBG
|
||||
#include <cstdio>
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// debug prints
|
||||
|
||||
#ifndef RYML_DBG
|
||||
# define _c4dbgt(fmt, ...)
|
||||
# define _c4dbgpf(fmt, ...)
|
||||
# define _c4dbgpf_(fmt, ...)
|
||||
# define _c4dbgp(msg)
|
||||
# define _c4dbgp_(msg)
|
||||
# define _c4dbgq(msg)
|
||||
# define _c4presc(...)
|
||||
# define _c4prscalar(msg, scalar, keep_newlines)
|
||||
#else
|
||||
# define _c4dbgt(fmt, ...) do { if(_dbg_enabled()) { \
|
||||
this->_dbg ("{}:{}: " fmt , __FILE__, __LINE__, __VA_ARGS__); } } while(0)
|
||||
# define _c4dbgpf(fmt, ...) _dbg_printf("{}:{}: " fmt "\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||
# define _c4dbgpf_(fmt, ...) _dbg_printf("{}:{}: " fmt , __FILE__, __LINE__, __VA_ARGS__)
|
||||
# define _c4dbgp(msg) _dbg_printf("{}:{}: " msg "\n", __FILE__, __LINE__ )
|
||||
# define _c4dbgp_(msg) _dbg_printf("{}:{}: " msg , __FILE__, __LINE__ )
|
||||
# define _c4dbgq(msg) _dbg_printf(msg "\n")
|
||||
# define _c4presc(...) do { if(_dbg_enabled()) __c4presc(__VA_ARGS__); } while(0)
|
||||
# define _c4prscalar(msg, scalar, keep_newlines) \
|
||||
do { \
|
||||
_c4dbgpf_("{}: [{}]~~~", msg, scalar.len); \
|
||||
if(_dbg_enabled()) { \
|
||||
__c4presc((scalar).str, (scalar).len, (keep_newlines)); \
|
||||
} \
|
||||
_c4dbgq("~~~"); \
|
||||
} while(0)
|
||||
#endif // RYML_DBG
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef RYML_DBG
|
||||
|
||||
#include <c4/dump.hpp>
|
||||
namespace c4 {
|
||||
inline bool& _dbg_enabled() { static bool enabled = true; return enabled; }
|
||||
inline void _dbg_set_enabled(bool yes) { _dbg_enabled() = yes; }
|
||||
inline void _dbg_dumper(csubstr s)
|
||||
{
|
||||
if(s.str)
|
||||
fwrite(s.str, 1, s.len, stdout);
|
||||
}
|
||||
inline substr _dbg_buf() noexcept
|
||||
{
|
||||
static char writebuf[2048];
|
||||
return substr{writebuf, sizeof(writebuf)}; // g++-5 has trouble with return writebuf;
|
||||
}
|
||||
template<class ...Args>
|
||||
C4_NO_INLINE void _dbg_printf(c4::csubstr fmt, Args const& ...args)
|
||||
{
|
||||
if(_dbg_enabled())
|
||||
{
|
||||
substr buf = _dbg_buf();
|
||||
const size_t needed_size = c4::format_dump(&_dbg_dumper, buf, fmt, args...);
|
||||
C4_CHECK(needed_size <= buf.len);
|
||||
}
|
||||
}
|
||||
inline C4_NO_INLINE void __c4presc(const char *s, size_t len, bool keep_newlines=false)
|
||||
{
|
||||
RYML_ASSERT(s || !len);
|
||||
size_t prev = 0;
|
||||
for(size_t i = 0; i < len; ++i)
|
||||
{
|
||||
switch(s[i])
|
||||
{
|
||||
case '\n' : _dbg_printf("{}{}{}", csubstr(s+prev, i-prev), csubstr("\\n"), csubstr(keep_newlines ? "\n":"")); prev = i+1; break;
|
||||
case '\t' : _dbg_printf("{}{}", csubstr(s+prev, i-prev), csubstr("\\t")); prev = i+1; break;
|
||||
case '\0' : _dbg_printf("{}{}", csubstr(s+prev, i-prev), csubstr("\\0")); prev = i+1; break;
|
||||
case '\r' : _dbg_printf("{}{}", csubstr(s+prev, i-prev), csubstr("\\r")); prev = i+1; break;
|
||||
case '\f' : _dbg_printf("{}{}", csubstr(s+prev, i-prev), csubstr("\\f")); prev = i+1; break;
|
||||
case '\b' : _dbg_printf("{}{}", csubstr(s+prev, i-prev), csubstr("\\b")); prev = i+1; break;
|
||||
case '\v' : _dbg_printf("{}{}", csubstr(s+prev, i-prev), csubstr("\\v")); prev = i+1; break;
|
||||
case '\a' : _dbg_printf("{}{}", csubstr(s+prev, i-prev), csubstr("\\a")); prev = i+1; break;
|
||||
case '\x1b': _dbg_printf("{}{}", csubstr(s+prev, i-prev), csubstr("\\x1b")); prev = i+1; break;
|
||||
case -0x3e/*0xc2u*/:
|
||||
if(i+1 < len)
|
||||
{
|
||||
if(s[i+1] == -0x60/*0xa0u*/)
|
||||
{
|
||||
_dbg_printf("{}{}", csubstr(s+prev, i-prev), csubstr("\\_")); prev = i+1;
|
||||
}
|
||||
else if(s[i+1] == -0x7b/*0x85u*/)
|
||||
{
|
||||
_dbg_printf("{}{}", csubstr(s+prev, i-prev), csubstr("\\N")); prev = i+1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case -0x1e/*0xe2u*/:
|
||||
if(i+2 < len && s[i+1] == -0x80/*0x80u*/)
|
||||
{
|
||||
if(s[i+2] == -0x58/*0xa8u*/)
|
||||
{
|
||||
_dbg_printf("{}{}", csubstr(s+prev, i-prev), csubstr("\\L")); prev = i+1;
|
||||
}
|
||||
else if(s[i+2] == -0x57/*0xa9u*/)
|
||||
{
|
||||
_dbg_printf("{}{}", csubstr(s+prev, i-prev), csubstr("\\P")); prev = i+1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(len > prev)
|
||||
_dbg_printf("{}", csubstr(s+prev, len-prev));
|
||||
}
|
||||
inline void __c4presc(csubstr s, bool keep_newlines=false)
|
||||
{
|
||||
__c4presc(s.str, s.len, keep_newlines);
|
||||
}
|
||||
} // namespace c4
|
||||
|
||||
#endif // RYML_DBG
|
||||
|
||||
#endif /* _C4_YML_DETAIL_DBGPRINT_HPP_ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user