diff --git a/CMakeLists.txt b/CMakeLists.txt index d8d2ac2..6106e79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ include_directories(external/imgui) include_directories(external/tinygltf) include_directories(external/ktx/include) include_directories(external/ktx/other_include) +include_directories(external/toml11) include_directories(base) OPTION(USE_D2D_WSI "Build the project using Direct to Display swapchain" OFF) diff --git a/base/VulkanTools.cpp b/base/VulkanTools.cpp index 33bb259..68149ae 100644 --- a/base/VulkanTools.cpp +++ b/base/VulkanTools.cpp @@ -10,17 +10,16 @@ const std::string getAssetPath() return ""; #elif defined(VK_EXAMPLE_DATA_DIR) - if (_access("./../data/", 0) != -1) + if (std::filesystem::exists("./../data/")) { - return "./../data/"; } - else if (_access("./data/", 0) != -1) + else if (std::filesystem::exists("./data/")) { return "./data/"; } - else if (_access("./../../data/", 0) != -1) + else if (std::filesystem::exists("./../../data/")) { return "../../data/"; diff --git a/base/VulkanTools.h b/base/VulkanTools.h index b7f55bc..d2e69b6 100644 --- a/base/VulkanTools.h +++ b/base/VulkanTools.h @@ -16,6 +16,7 @@ #include #include #include +#include #if defined(_WIN32) #include #include diff --git a/data/output/video/device0/result.mp4 b/data/output/video/device0/result.mp4 index 6b042b8..92d286e 100644 Binary files a/data/output/video/device0/result.mp4 and b/data/output/video/device0/result.mp4 differ diff --git a/external/toml11/.circleci/config.yml b/external/toml11/.circleci/config.yml new file mode 100644 index 0000000..cd77392 --- /dev/null +++ b/external/toml11/.circleci/config.yml @@ -0,0 +1,88 @@ +version: 2.1 + +jobs: + test_suite: + docker: + - image: cimg/go:1.16 + steps: + - checkout + - run: + command: | + g++ --version + cd tests/ + g++ -std=c++11 -O2 -Wall -Wextra -Werror -I../ check_toml_test.cpp -o check_toml_test + export PATH=$(pwd):${PATH} + git clone --depth 1 --branch v1.3.0 https://github.com/BurntSushi/toml-test.git + cd toml-test/ + go install -v ./cmd/toml-test + cd - + toml-test check_toml_test +# go clean -modcache +# go get github.com/BurntSushi/toml-test/cmd/toml-test +# $GOPATH/bin/toml-test ./check_toml_test + test_serialization: + docker: + - image: circleci/buildpack-deps:bionic + steps: + - checkout + - run: + command: | + g++ --version + cd tests/ + g++ -std=c++11 -O2 -Wall -Wextra -Wpedantic -Werror -I../ check_serialization.cpp -o check_serialization + git clone https://github.com/BurntSushi/toml-test.git + cp check_serialization toml-test/tests/valid + cd toml-test/tests/valid + for f in $(ls ./*.toml); + do echo "==> ${f}"; + cat ${f}; + echo "---------------------------------------"; + ./check_serialization ${f}; + if [ $? -ne 0 ] ; then + exit 1 + fi + echo "======================================="; + done + output_result: + docker: + - image: circleci/buildpack-deps:bionic + steps: + - checkout + - run: + command: | + g++ --version + cd tests/ + g++ -std=c++11 -O2 -Wall -Wextra -Wpedantic -Werror -I../ check.cpp -o check + git clone https://github.com/BurntSushi/toml-test.git + cp check toml-test/tests/invalid + cp check toml-test/tests/valid + cd toml-test/tests/invalid + for f in $(ls ./*.toml); + do echo "==> ${f}"; + cat ${f}; + echo "---------------------------------------"; + ./check ${f} invalid; + if [ $? -ne 0 ] ; then + exit 1 + fi + echo "======================================="; + done + cd ../valid + for f in $(ls ./*.toml); + do echo "==> ${f}"; + cat ${f}; + echo "---------------------------------------"; + ./check ${f} valid; + if [ $? -ne 0 ] ; then + exit 1 + fi + echo "======================================="; + done + +workflows: + version: 2.1 + test: + jobs: + - test_suite + - test_serialization + - output_result diff --git a/external/toml11/.clusterfuzzlite/Dockerfile b/external/toml11/.clusterfuzzlite/Dockerfile new file mode 100644 index 0000000..4206e01 --- /dev/null +++ b/external/toml11/.clusterfuzzlite/Dockerfile @@ -0,0 +1,6 @@ +FROM gcr.io/oss-fuzz-base/base-builder +RUN apt-get update && apt-get install -y make autoconf automake libtool + +COPY . $SRC/toml11 +COPY .clusterfuzzlite/build.sh $SRC/build.sh +WORKDIR $SRC/toml11 diff --git a/external/toml11/.clusterfuzzlite/README.md b/external/toml11/.clusterfuzzlite/README.md new file mode 100644 index 0000000..4ee95c0 --- /dev/null +++ b/external/toml11/.clusterfuzzlite/README.md @@ -0,0 +1,3 @@ +# ClusterFuzzLite set up + +This folder contains a fuzzing set for [ClusterFuzzLite](https://google.github.io/clusterfuzzlite). diff --git a/external/toml11/.clusterfuzzlite/build.sh b/external/toml11/.clusterfuzzlite/build.sh new file mode 100644 index 0000000..c6d57fd --- /dev/null +++ b/external/toml11/.clusterfuzzlite/build.sh @@ -0,0 +1,6 @@ +#!/bin/bash -eu +# Copy fuzzer executable to $OUT/ +$CXX $CFLAGS $LIB_FUZZING_ENGINE \ + $SRC/toml11/.clusterfuzzlite/parse_fuzzer.cpp \ + -o $OUT/parse_fuzzer \ + -I$SRC/toml11/ diff --git a/external/toml11/.clusterfuzzlite/parse_fuzzer.cpp b/external/toml11/.clusterfuzzlite/parse_fuzzer.cpp new file mode 100644 index 0000000..23bda4d --- /dev/null +++ b/external/toml11/.clusterfuzzlite/parse_fuzzer.cpp @@ -0,0 +1,16 @@ + +#include + +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + std::string s(reinterpret_cast(data), size); + std::istringstream iss(s); + try { + const auto ref = toml::parse(iss); + } catch (...) { + } + + return 0; +} diff --git a/external/toml11/.clusterfuzzlite/project.yaml b/external/toml11/.clusterfuzzlite/project.yaml new file mode 100644 index 0000000..b478801 --- /dev/null +++ b/external/toml11/.clusterfuzzlite/project.yaml @@ -0,0 +1 @@ +language: c++ diff --git a/external/toml11/.editorconfig b/external/toml11/.editorconfig new file mode 100644 index 0000000..05bbdec --- /dev/null +++ b/external/toml11/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +indent_style = space + +[CMakeLists.txt] +indent_size = 4 + +[*.{c,h}*] +indent_size = 4 + +[*.{md,yml}] +indent_size = 2 diff --git a/external/toml11/.github/workflows/cflite_pr.yml b/external/toml11/.github/workflows/cflite_pr.yml new file mode 100644 index 0000000..541a6ce --- /dev/null +++ b/external/toml11/.github/workflows/cflite_pr.yml @@ -0,0 +1,30 @@ +name: ClusterFuzzLite PR fuzzing +on: + workflow_dispatch: + pull_request: + branches: [ master ] +permissions: read-all +jobs: + PR: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sanitizer: [address] + steps: + - name: Build Fuzzers (${{ matrix.sanitizer }}) + id: build + uses: google/clusterfuzzlite/actions/build_fuzzers@v1 + with: + sanitizer: ${{ matrix.sanitizer }} + language: c++ + bad-build-check: false + - name: Run Fuzzers (${{ matrix.sanitizer }}) + id: run + uses: google/clusterfuzzlite/actions/run_fuzzers@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + fuzz-seconds: 240 + mode: 'code-change' + report-unreproducible-crashes: false + sanitizer: ${{ matrix.sanitizer }} diff --git a/external/toml11/.github/workflows/main.yml b/external/toml11/.github/workflows/main.yml new file mode 100644 index 0000000..4126385 --- /dev/null +++ b/external/toml11/.github/workflows/main.yml @@ -0,0 +1,280 @@ +name: build + +on: [push, pull_request] + +jobs: + build-linux-gcc: + runs-on: Ubuntu-22.04 + strategy: + matrix: + compiler: ['g++-12', 'g++-11', 'g++-10', 'g++-9'] + standard: ['11', '14', '17', '20'] + unreleased: ['ON', 'OFF'] + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: true + - name: Install + run: | + sudo apt-add-repository ppa:ubuntu-toolchain-r/test + sudo apt-get update + sudo apt-get install libboost-test-dev + sudo apt-get install language-pack-fr # test serializer w/ locale + sudo apt-get install ${{ matrix.compiler }} + - name: Configure + run: | + mkdir build && cd build + cmake .. -Dtoml11_BUILD_TEST=ON -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_USE_UNRELEASED_TOML_FEATURES=${{ matrix.unreleased }} + - name: Build + run: | + cd build && cmake --build . + - name: Test + run: | + cd build && ctest --output-on-failure + build-linux-clang: + runs-on: Ubuntu-22.04 + strategy: + matrix: + compiler: ['15', '14', '13', '12', '11'] + standard: ['11', '14', '17', '20'] + unreleased: ['ON', 'OFF'] + exclude: + - {compiler: '14', standard: '20'} # to avoid using gcc-13 libstdc++ + - {compiler: '13', standard: '20'} # with older clang + - {compiler: '12', standard: '20'} + - {compiler: '11', standard: '20'} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: true + - name: Install + run: | + sudo apt-add-repository ppa:ubuntu-toolchain-r/test + sudo apt-get update + sudo apt-get install libboost-test-dev + sudo apt-get install language-pack-fr # test serializer w/ locale + sudo apt-get install clang-${{ matrix.compiler }} + - name: Configure + run: | + mkdir build && cd build + cmake .. -Dtoml11_BUILD_TEST=ON -DCMAKE_C_COMPILER=clang-${{ matrix.compiler }} -DCMAKE_CXX_COMPILER=clang++-${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_USE_UNRELEASED_TOML_FEATURES=${{ matrix.unreleased }} + - name: Build + run: | + cd build && cmake --build . + - name: Test + run: | + cd build && ctest --output-on-failure + + build-linux-old-gcc: + runs-on: Ubuntu-20.04 + strategy: + matrix: + compiler: ['g++-8', 'g++-7'] + standard: ['11', '14', '17', '20'] + unreleased: ['ON', 'OFF'] + exclude: + - {compiler: 'g++-7', standard: '20'} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: true + - name: Install + run: | + sudo apt-add-repository ppa:ubuntu-toolchain-r/test + sudo apt-get update + sudo apt-get install libboost-test-dev + sudo apt-get install language-pack-fr # test serializer w/ locale + sudo apt-get install ${{ matrix.compiler }} + - name: Configure + run: | + mkdir build && cd build + if [[ "${{ matrix.compiler }}" == "g++-8" && ( "${{ matrix.standard }}" == "17" || "${{ matrix.standard }}" == "20" ) ]] ; then + cmake .. -Dtoml11_BUILD_TEST=ON -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_REQUIRE_FILESYSTEM_LIBRARY=ON -DTOML11_USE_UNRELEASED_TOML_FEATURES=${{ matrix.unreleased }} + else + cmake .. -Dtoml11_BUILD_TEST=ON -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_USE_UNRELEASED_TOML_FEATURES=${{ matrix.unreleased }} + fi + - name: Build + run: | + cd build && cmake --build . + - name: Test + run: | + cd build && ctest --output-on-failure + + build-linux-old-clang: + runs-on: Ubuntu-20.04 + strategy: + matrix: + compiler: ['10', '9', '8', '7', '6.0'] + standard: ['11', '14', '17', '20'] + unreleased: ['ON', 'OFF'] + exclude: + - {compiler: '6.0', standard: '20'} + - {compiler: '7', standard: '20'} + - {compiler: '8', standard: '20'} + - {compiler: '9', standard: '20'} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: true + - name: Install + run: | + sudo apt-add-repository ppa:ubuntu-toolchain-r/test + sudo apt-get update + sudo apt-get install libboost-test-dev + sudo apt-get install language-pack-fr # test serializer w/ locale + sudo apt-get install clang-${{ matrix.compiler }} + - name: Configure + run: | + mkdir build && cd build + cmake .. -Dtoml11_BUILD_TEST=ON -DCMAKE_C_COMPILER=clang-${{ matrix.compiler }} -DCMAKE_CXX_COMPILER=clang++-${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_USE_UNRELEASED_TOML_FEATURES=${{ matrix.unreleased }} + - name: Build + run: | + cd build && cmake --build . + - name: Test + run: | + cd build && ctest --output-on-failure + +# build-osx-13-arm64: +# runs-on: macos-13-arm64 +# strategy: +# matrix: +# standard: ['11', '14', '17', '20'] +# unreleased: ['ON', 'OFF'] +# steps: +# - name: Checkout +# uses: actions/checkout@v3 +# with: +# submodules: true +# - name: Install +# run: | +# brew install boost +# - name: Configure +# run: | +# mkdir build && cd build +# cmake .. -Dtoml11_BUILD_TEST=ON -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_USE_UNRELEASED_TOML_FEATURES=${{ matrix.unreleased }} +# - name: Build +# run: | +# cd build && cmake --build . +# - name: Test +# run: | +# cd build && ctest --output-on-failure + + build-osx-13: + runs-on: macos-13 + strategy: + matrix: + standard: ['11', '14', '17', '20'] + unreleased: ['ON', 'OFF'] + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: true + - name: Install + run: | + brew install boost + - name: Configure + run: | + mkdir build && cd build + cmake .. -Dtoml11_BUILD_TEST=ON -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_USE_UNRELEASED_TOML_FEATURES=${{ matrix.unreleased }} + - name: Build + run: | + cd build && cmake --build . + - name: Test + run: | + cd build && ctest --output-on-failure + + build-osx-12: + runs-on: macos-12 + strategy: + matrix: + standard: ['11', '14', '17', '20'] + unreleased: ['ON', 'OFF'] + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: true + - name: Install + run: | + brew install boost + - name: Configure + run: | + mkdir build && cd build + cmake .. -Dtoml11_BUILD_TEST=ON -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_USE_UNRELEASED_TOML_FEATURES=${{ matrix.unreleased }} + - name: Build + run: | + cd build && cmake --build . + - name: Test + run: | + cd build && ctest --output-on-failure + + + build-osx-11: + runs-on: macos-11 + strategy: + matrix: + standard: ['11', '14', '17', '20'] + unreleased: ['ON', 'OFF'] + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: true + - name: Install + run: | + brew install boost + - name: Configure + run: | + mkdir build && cd build + cmake .. -Dtoml11_BUILD_TEST=ON -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_USE_UNRELEASED_TOML_FEATURES=${{ matrix.unreleased }} + - name: Build + run: | + cd build && cmake --build . + - name: Test + run: | + cd build && ctest --output-on-failure + + build-windows-msvc: + runs-on: windows-2022 + strategy: + matrix: + standard: ['11', '14', '17', '20'] + config: ['Release', 'Debug'] + unreleased: ['ON', 'OFF'] + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: true + - name: Install + run: | + (New-Object System.Net.WebClient).DownloadFile("https://github.com/actions/boost-versions/releases/download/1.72.0-20200608.4/boost-1.72.0-win32-msvc14.2-x86_64.tar.gz", "$env:TEMP\\boost.tar.gz") + 7z.exe x "$env:TEMP\\boost.tar.gz" -o"$env:TEMP\\boostArchive" -y | Out-Null + 7z.exe x "$env:TEMP\\boostArchive" -o"$env:TEMP\\boost" -y | Out-Null + Push-Location -Path "$env:TEMP\\boost" + Invoke-Expression .\\setup.ps1 + - uses: ilammy/msvc-dev-cmd@v1 + - name: Configure + shell: cmd + run: | + file --mime-encoding tests/test_literals.cpp + mkdir build + cd build + cmake ../ -G "NMake Makefiles" -Dtoml11_BUILD_TEST=ON -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DBoost_NO_BOOST_CMAKE=ON -DBOOST_ROOT="C:\\hostedtoolcache\\windows\\Boost\\1.72.0\\x86_64" -DTOML11_USE_UNRELEASED_TOML_FEATURES=${{ matrix.unreleased }} + - name: Build + working-directory: ./build + run: | + cmake --build . --config "${{ matrix.config }}" + - name: Test + working-directory: ./build + run: | + file --mime-encoding tests/toml/tests/example.toml + file --mime-encoding tests/toml/tests/fruit.toml + file --mime-encoding tests/toml/tests/hard_example.toml + file --mime-encoding tests/toml/tests/hard_example_unicode.toml + ctest --build-config "${{ matrix.config }}" --output-on-failure diff --git a/external/toml11/.gitignore b/external/toml11/.gitignore new file mode 100644 index 0000000..a007fea --- /dev/null +++ b/external/toml11/.gitignore @@ -0,0 +1 @@ +build/* diff --git a/external/toml11/CMakeLists.txt b/external/toml11/CMakeLists.txt new file mode 100644 index 0000000..ddaa812 --- /dev/null +++ b/external/toml11/CMakeLists.txt @@ -0,0 +1,121 @@ +cmake_minimum_required(VERSION 3.5) +enable_testing() + +project(toml11 VERSION 3.8.1) + +option(toml11_BUILD_TEST "Build toml tests" OFF) +option(toml11_INSTALL "Install CMake targets during install step." ON) +option(toml11_TEST_WITH_ASAN "use LLVM address sanitizer" OFF) +option(toml11_TEST_WITH_UBSAN "use LLVM undefined behavior sanitizer" OFF) + +option(TOML11_USE_UNRELEASED_TOML_FEATURES + "use features in toml-lang/toml master while testing" OFF) + +include(CheckCXXCompilerFlag) +if("${CMAKE_VERSION}" VERSION_GREATER 3.1) + set(CMAKE_CXX_EXTENSIONS OFF CACHE BOOL "Boolean specifying whether compiler specific extensions are requested.") + if(NOT DEFINED CMAKE_CXX_STANDARD) + message(FATAL_ERROR "CMAKE_CXX_STANDARD is not defined. \ +The C++ standard whose features are requested to *build* all targets. \ +Remember that toml11 is a header only library that does NOT require compilation to use.") + endif() + set(CMAKE_CXX_STANDARD_REQUIRED ON CACHE BOOL "Boolean describing whether the value of CXX_STANDARD is a requirement.") +else() + # Manually check for C++11 compiler flag. + CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) + CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) + CHECK_CXX_COMPILER_FLAG("-std=gnu++11" COMPILER_SUPPORTS_GNU11) + CHECK_CXX_COMPILER_FLAG("-std=gnu++0x" COMPILER_SUPPORTS_GNU0X) + if(COMPILER_SUPPORTS_CXX11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + elseif(COMPILER_SUPPORTS_CXXOX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") + elseif(COMPILER_SUPPORTS_GNU11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") + elseif(COMPILER_SUPPORTS_GNU0X) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x") + else() + if(MSVC) + if(MSVC_VERSION LESS 1900) + message(SEND_ERROR "MSVC < 14.0 is not supported. Please update your compiler or use mingw") + endif() + else() + message(SEND_ERROR "The ${CMAKE_CXX_COMPILER} compiler lacks C++11 support. Use another compiler.") + endif() + endif() +endif() + +if(MSVC) +# add_definitions("/Zc:__cplusplus") # define __cplusplus value correctly + add_definitions("/utf-8") # enable to use u8"" literal + if(MSVC_VERSION LESS 1910) + message(STATUS "MSVC < 1910. DEFINE_CONVERSION_NON_INTRUSIVE is disabled") + add_definitions(-DTOML11_WITHOUT_DEFINE_NON_INTRUSIVE) + elseif(MSVC_VERSION LESS 1920) + add_definitions("/experimental:preprocessor") # MSVC 2017 + else() + add_definitions("/Zc:preprocessor") # MSVC 2019 + endif() +endif() + +# Set some common directories +include(GNUInstallDirs) +set(toml11_install_cmake_dir ${CMAKE_INSTALL_LIBDIR}/cmake/toml11) +set(toml11_install_include_dir ${CMAKE_INSTALL_INCLUDEDIR}) +set(toml11_config_dir ${CMAKE_CURRENT_BINARY_DIR}/cmake/) +set(toml11_config ${toml11_config_dir}/toml11Config.cmake) +set(toml11_config_version ${toml11_config_dir}/toml11ConfigVersion.cmake) + +add_library(toml11 INTERFACE) +target_include_directories(toml11 INTERFACE + $ + $ +) +add_library(toml11::toml11 ALIAS toml11) + +# Write config and version config files +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + ${toml11_config_version} + VERSION ${toml11_VERSION} + COMPATIBILITY SameMajorVersion +) + +if (toml11_INSTALL) + configure_package_config_file( + cmake/toml11Config.cmake.in + ${toml11_config} + INSTALL_DESTINATION ${toml11_install_cmake_dir} + PATH_VARS toml11_install_cmake_dir + ) + + # Install config files + install(FILES ${toml11_config} ${toml11_config_version} + DESTINATION ${toml11_install_cmake_dir} + ) + + # Install header files + install( + FILES toml.hpp + DESTINATION "${toml11_install_include_dir}" + ) + install( + DIRECTORY "toml" + DESTINATION "${toml11_install_include_dir}" + FILES_MATCHING PATTERN "*.hpp" + ) + + # Export targets and install them + install(TARGETS toml11 + EXPORT toml11Targets + ) + install(EXPORT toml11Targets + FILE toml11Targets.cmake + DESTINATION ${toml11_install_cmake_dir} + NAMESPACE toml11:: + ) +endif() + +if (toml11_BUILD_TEST) + add_subdirectory(tests) +endif () diff --git a/external/toml11/LICENSE b/external/toml11/LICENSE new file mode 100644 index 0000000..f55c511 --- /dev/null +++ b/external/toml11/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Toru Niina + +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. diff --git a/external/toml11/README.md b/external/toml11/README.md new file mode 100644 index 0000000..fd8b18e --- /dev/null +++ b/external/toml11/README.md @@ -0,0 +1,2082 @@ +toml11 +====== + +[![Build Status on GitHub Actions](https://github.com/ToruNiina/toml11/workflows/build/badge.svg)](https://github.com/ToruNiina/toml11/actions) +[![Build status on Appveyor](https://ci.appveyor.com/api/projects/status/m2n08a926asvg5mg/branch/master?svg=true)](https://ci.appveyor.com/project/ToruNiina/toml11/branch/master) +[![Build status on CircleCI](https://circleci.com/gh/ToruNiina/toml11/tree/master.svg?style=svg)](https://circleci.com/gh/ToruNiina/toml11/tree/master) +[![Version](https://img.shields.io/github/release/ToruNiina/toml11.svg?style=flat)](https://github.com/ToruNiina/toml11/releases) +[![License](https://img.shields.io/github/license/ToruNiina/toml11.svg?style=flat)](LICENSE) +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1209136.svg)](https://doi.org/10.5281/zenodo.1209136) + +toml11 is a C++11 (or later) header-only toml parser/encoder depending only on C++ standard library. + +- It is compatible to the latest version of [TOML v1.0.0](https://toml.io/en/v1.0.0). +- It is one of the most TOML standard compliant libraries, tested with [the language agnostic test suite for TOML parsers by BurntSushi](https://github.com/BurntSushi/toml-test). +- It shows highly informative error messages. You can see the error messages about invalid files at [CircleCI](https://circleci.com/gh/ToruNiina/toml11). +- It has configurable container. You can use any random-access containers and key-value maps as backend containers. +- It optionally preserves comments without any overhead. +- It has configurable serializer that supports comments, inline tables, literal strings and multiline strings. +- It supports user-defined type conversion from/into toml values. +- It correctly handles UTF-8 sequences, with or without BOM, both on posix and Windows. + +## Example + +```cpp +#include +#include + +int main() +{ + // ```toml + // title = "an example toml file" + // nums = [3, 1, 4, 1, 5] + // ``` + auto data = toml::parse("example.toml"); + + // find a value with the specified type from a table + std::string title = toml::find(data, "title"); + + // convert the whole array into any container automatically + std::vector nums = toml::find>(data, "nums"); + + // access with STL-like manner + if(!data.contains("foo")) + { + data["foo"] = "bar"; + } + + // pass a fallback + std::string name = toml::find_or(data, "name", "not found"); + + // width-dependent formatting + std::cout << std::setw(80) << data << std::endl; + + return 0; +} +``` + +## Table of Contents + +- [Integration](#integration) +- [Decoding a toml file](#decoding-a-toml-file) + - [In the case of syntax error](#in-the-case-of-syntax-error) + - [Invalid UTF-8 Codepoints](#invalid-utf-8-codepoints) +- [Finding a toml value](#finding-a-toml-value) + - [Finding a value in a table](#finding-a-value-in-a-table) + - [In case of error](#in-case-of-error) + - [Dotted keys](#dotted-keys) +- [Casting a toml value](#casting-a-toml-value) +- [Checking value type](#checking-value-type) +- [More about conversion](#more-about-conversion) + - [Converting an array](#converting-an-array) + - [Converting a table](#converting-a-table) + - [Getting an array of tables](#getting-an-array-of-tables) + - [Cost of conversion](#cost-of-conversion) + - [Converting datetime and its variants](#converting-datetime-and-its-variants) +- [Getting with a fallback](#getting-with-a-fallback) +- [Expecting conversion](#expecting-conversion) +- [Visiting a toml::value](#visiting-a-tomlvalue) +- [Constructing a toml::value](#constructing-a-tomlvalue) +- [Preserving Comments](#preserving-comments) +- [Customizing containers](#customizing-containers) +- [TOML literal](#toml-literal) +- [Conversion between toml value and arbitrary types](#conversion-between-toml-value-and-arbitrary-types) +- [Formatting user-defined error messages](#formatting-user-defined-error-messages) +- [Obtaining location information](#obtaining-location-information) +- [Exceptions](#exceptions) +- [Colorize Error Messages](#colorize-error-messages) +- [Serializing TOML data](#serializing-toml-data) +- [Underlying types](#underlying-types) +- [Unreleased TOML features](#unreleased-toml-features) +- [Breaking Changes from v2](#breaking-changes-from-v2) +- [Running Tests](#running-tests) +- [Contributors](#contributors) +- [Licensing Terms](#licensing-terms) + +## Integration + +Just include the file after adding it to the include path. + +```cpp +#include // that's all! now you can use it. +#include + +int main() +{ + const auto data = toml::parse("example.toml"); + const auto title = toml::find(data, "title"); + std::cout << "the title is " << title << std::endl; + return 0; +} +``` + +The convenient way is to add this repository as a git-submodule or to install +it in your system by CMake. + +Note for MSVC: We recommend to set `/Zc:__cplusplus` to detect C++ version correctly. + +### Example installation + +For local installation build & use the provided install target + +```bash +git clone https://github.com/ToruNiina/toml11.git +mkdir -p toml11/build +cd toml11/build +cmake .. -DCMAKE_CXX_STANDARD=11 +sudo make install +``` + +In case you want to create a `.deb` you can use `checkinstall`. +```bash +sudo checkinstall +[[ .. skipping for clarity ]] +********************************************************************** + + Done. The new package has been installed and saved to + + /home/user/toml11/build/build_20230728-1_amd64.deb + + You can remove it from your system anytime using: + + dpkg -r build + +********************************************************************** +``` + +You should get a package that you can install with `dpkg -i .deb` and remove with `dpkg -r .deb` + +## Decoding a toml file + +To parse a toml file, the only thing you have to do is +to pass a filename to the `toml::parse` function. + +```cpp +const std::string fname("sample.toml"); +const toml::value data = toml::parse(fname); +``` + +As required by the TOML specification, the top-level value is always a table. +You can find a value inside it, cast it into a table explicitly, and insert it as a value into other `toml::value`. + +If it encounters an error while opening a file, it will throw `std::runtime_error`. + +You can also pass a `std::istream` to the `toml::parse` function. +To show a filename in an error message, however, it is recommended to pass the +filename with the stream. + +```cpp +std::ifstream ifs("sample.toml", std::ios_base::binary); +assert(ifs.good()); +const auto data = toml::parse(ifs, /*optional -> */ "sample.toml"); +``` + +**Note**: When you are **on Windows, open a file in binary mode**. +If a file is opened in text-mode, CRLF ("\r\n") will automatically be +converted to LF ("\n") and this causes inconsistency between file size +and the contents that would be read. This causes weird error. + +### In the case of syntax error + +If there is a syntax error in a toml file, `toml::parse` will throw +`toml::syntax_error` that inherits `std::exception`. + +toml11 has clean and informative error messages inspired by Rust and +it looks like the following. + +```console +terminate called after throwing an instance of 'toml::syntax_error' + what(): [error] toml::parse_table: invalid line format # error description + --> example.toml # file name + 3 | a = 42 = true # line num and content + | ^------ expected newline, but got '='. # error reason +``` + +If you (mistakenly) duplicate tables and got an error, it is helpful to see +where they are. toml11 shows both at the same time like the following. + +```console +terminate called after throwing an instance of 'toml::syntax_error' + what(): [error] toml::insert_value: table ("table") already exists. + --> duplicate-table.toml + 1 | [table] + | ~~~~~~~ table already exists here + ... + 3 | [table] + | ~~~~~~~ table defined twice +``` + +When toml11 encounters a malformed value, it tries to detect what type it is. +Then it shows hints to fix the format. An error message while reading one of +the malformed files in [the language agnostic test suite](https://github.com/BurntSushi/toml-test). +is shown below. + +```console +what(): [error] bad time: should be HH:MM:SS.subsec + --> ./datetime-malformed-no-secs.toml + 1 | no-secs = 1987-07-05T17:45Z + | ^------- HH:MM:SS.subsec + | +Hint: pass: 1979-05-27T07:32:00, 1979-05-27 07:32:00.999999 +Hint: fail: 1979-05-27T7:32:00, 1979-05-27 17:32 +``` + +You can find other examples in a job named `output_result` on +[CircleCI](https://circleci.com/gh/ToruNiina/toml11). + +Since the error message generation is generally a difficult task, the current +status is not ideal. If you encounter a weird error message, please let us know +and contribute to improve the quality! + +### Invalid UTF-8 codepoints + +It throws `syntax_error` if a value of an escape sequence +representing unicode character is not a valid UTF-8 codepoint. + +```console + what(): [error] toml::read_utf8_codepoint: input codepoint is too large. + --> utf8.toml + 1 | exceeds_unicode = "\U0011FFFF example" + | ^--------- should be in [0x00..0x10FFFF] +``` + +## Finding a toml value + +After parsing successfully, you can obtain the values from the result of +`toml::parse` using `toml::find` function. + +```toml +# sample.toml +answer = 42 +pi = 3.14 +numbers = [1,2,3] +time = 1979-05-27T07:32:00Z +``` + +``` cpp +const auto data = toml::parse("sample.toml"); +const auto answer = toml::find(data, "answer"); +const auto pi = toml::find(data, "pi"); +const auto numbers = toml::find>(data, "numbers"); +const auto timepoint = toml::find(data, "time"); +``` + +By default, `toml::find` returns a `toml::value`. + +```cpp +const toml::value& answer = toml::find(data, "answer"); +``` + +When you pass an exact TOML type that does not require type conversion, +`toml::find` returns a reference without copying the value. + +```cpp +const auto data = toml::parse("sample.toml"); +const auto& answer = toml::find(data, "answer"); +``` + +If the specified type requires conversion, you can't take a reference to the value. +See also [underlying types](#underlying-types). + +**NOTE**: For some technical reason, automatic conversion between `integer` and +`floating` is not supported. If you want to get a floating value even if a value +has integer value, you need to convert it manually after obtaining a value, +like the following. + +```cpp +const auto vx = toml::find(data, "x"); +double x = vx.is_floating() ? vx.as_floating(std::nothrow) : + static_cast(vx.as_integer()); // it throws if vx is neither + // floating nor integer. +``` + +### Finding a value in a table + +There are several way to get a value defined in a table. +First, you can get a table as a normal value and find a value from the table. + +```toml +[fruit] +name = "apple" +[fruit.physical] +color = "red" +shape = "round" +``` + +``` cpp +const auto data = toml::parse("fruit.toml"); +const auto& fruit = toml::find(data, "fruit"); +const auto name = toml::find(fruit, "name"); + +const auto& physical = toml::find(fruit, "physical"); +const auto color = toml::find(physical, "color"); +const auto shape = toml::find(physical, "shape"); +``` + +Here, variable `fruit` is a `toml::value` and can be used as the first argument +of `toml::find`. + +Second, you can pass as many arguments as the number of subtables to `toml::find`. + +```cpp +const auto data = toml::parse("fruit.toml"); +const auto color = toml::find(data, "fruit", "physical", "color"); +const auto shape = toml::find(data, "fruit", "physical", "shape"); +``` + +### Finding a value in an array + +You can find n-th value in an array by `toml::find`. + +```toml +values = ["foo", "bar", "baz"] +``` + +``` cpp +const auto data = toml::parse("sample.toml"); +const auto values = toml::find(data, "values"); +const auto bar = toml::find(values, 1); +``` + +`toml::find` can also search array recursively. + +```cpp +const auto data = toml::parse("fruit.toml"); +const auto bar = toml::find(data, "values", 1); +``` + +Before calling `toml::find`, you can check if a value corresponding to a key +exists. You can use both `bool toml::value::contains(const key&) const` and +`std::size_t toml::value::count(const key&) const`. Those behaves like the +`std::map::contains` and `std::map::count`. + +```cpp +const auto data = toml::parse("fruit.toml"); +if(data.contains("fruit") && data.at("fruit").count("physical") != 0) +{ + // ... +} +``` + +### In case of error + +If the value does not exist, `toml::find` throws `std::out_of_range` with the +location of the table. + +```console +terminate called after throwing an instance of 'std::out_of_range' + what(): [error] key "answer" not found + --> example.toml + 6 | [tab] + | ~~~~~ in this table +``` + +---- + +If the specified type differs from the actual value contained, it throws +`toml::type_error` that inherits `std::exception`. + +Similar to the case of syntax error, toml11 also displays clean error messages. +The error message when you choose `int` to get `string` value would be like this. + +```console +terminate called after throwing an instance of 'toml::type_error' + what(): [error] toml::value bad_cast to integer + --> example.toml + 3 | title = "TOML Example" + | ~~~~~~~~~~~~~~ the actual type is string +``` + +**NOTE**: In order to show this kind of error message, all the toml values have +a pointer to represent its range in a file. The entire contents of a file is +shared by `toml::value`s and remains on the heap memory. It is recommended to +destruct all the `toml::value` classes after configuring your application +if you have a large TOML file compared to the memory resource. + +### Dotted keys + +TOML v0.5.0 has a new feature named "dotted keys". +You can chain keys to represent the structure of the data. + +```toml +physical.color = "orange" +physical.shape = "round" +``` + +This is equivalent to the following. + +```toml +[physical] +color = "orange" +shape = "round" +``` + +You can get both of the above tables with the same c++ code. + +```cpp +const auto physical = toml::find(data, "physical"); +const auto color = toml::find(physical, "color"); +``` + +The following code does not work for the above toml file. + +```cpp +// XXX this does not work! +const auto color = toml::find(data, "physical.color"); +``` + +The above code works with the following toml file. + +```toml +"physical.color" = "orange" +# equivalent to {"physical.color": "orange"}, +# NOT {"physical": {"color": "orange"}}. +``` + + +## Casting a toml value + +### `toml::get` + +`toml::parse` returns `toml::value`. `toml::value` is a union type that can +contain one of the following types. + +- `toml::boolean` (`bool`) +- `toml::integer` (`std::int64_t`) +- `toml::floating` (`double`) +- `toml::string` (a type convertible to std::string) +- `toml::local_date` +- `toml::local_time` +- `toml::local_datetime` +- `toml::offset_datetime` +- `toml::array` (by default, `std::vector`) + - It depends. See [customizing containers](#customizing-containers) for detail. +- `toml::table` (by default, `std::unordered_map`) + - It depends. See [customizing containers](#customizing-containers) for detail. + +To get a value inside, you can use `toml::get()`. The usage is the same as +`toml::find` (actually, `toml::find` internally uses `toml::get` after casting +a value to `toml::table`). + +``` cpp +const toml::value data = toml::parse("sample.toml"); +const toml::value answer_ = toml::get(data).at("answer"); +const std::int64_t answer = toml::get(answer_); +``` + +When you pass an exact TOML type that does not require type conversion, +`toml::get` returns a reference through which you can modify the content +(if the `toml::value` is `const`, it returns `const` reference). + +```cpp +toml::value data = toml::parse("sample.toml"); +toml::value answer_ = toml::get(data).at("answer"); +toml::integer& answer = toml::get(answer_); +answer = 6 * 9; // write to data.answer. now `answer_` contains 54. +``` + +If the specified type requires conversion, you can't take a reference to the value. +See also [underlying types](#underlying-types). + +It also throws a `toml::type_error` if the type differs. + +### `as_xxx` + +You can also use a member function to cast a value. + +```cpp +const std::int64_t answer = data.as_table().at("answer").as_integer(); +``` + +It also throws a `toml::type_error` if the type differs. If you are sure that +the value `v` contains a value of the specified type, you can suppress checking +by passing `std::nothrow`. + +```cpp +const auto& answer = data.as_table().at("answer"); +if(answer.is_integer() && answer.as_integer(std::nothrow) == 42) +{ + std::cout << "value is 42" << std::endl; +} +``` + +If `std::nothrow` is passed, the functions are marked as noexcept. + +By casting a `toml::value` into an array or a table, you can iterate over the +elements. + +```cpp +const auto data = toml::parse("example.toml"); +std::cout << "keys in the top-level table are the following: \n"; +for(const auto& kv : data.as_table()) +{ + std::cout << kv.first << '\n'; +} +for(const auto& [k, v] : data.as_table()) // or in C++17 +{ + std::cout << k << '\n'; +} + + +const auto& fruits = toml::find(data, "fruits"); +for(const auto& v : fruits.as_array()) +{ + std::cout << toml::find(v, "name") << '\n'; +} +``` + +The full list of the functions is below. + +```cpp +namespace toml { +class value { + // ... + const boolean& as_boolean() const&; + const integer& as_integer() const&; + const floating& as_floating() const&; + const string& as_string() const&; + const offset_datetime& as_offset_datetime() const&; + const local_datetime& as_local_datetime() const&; + const local_date& as_local_date() const&; + const local_time& as_local_time() const&; + const array& as_array() const&; + const table& as_table() const&; + // -------------------------------------------------------- + // non-const version + boolean& as_boolean() &; + // ditto... + // -------------------------------------------------------- + // rvalue version + boolean&& as_boolean() &&; + // ditto... + + // -------------------------------------------------------- + // noexcept versions ... + const boolean& as_boolean(const std::nothrow_t&) const& noexcept; + boolean& as_boolean(const std::nothrow_t&) & noexcept; + boolean&& as_boolean(const std::nothrow_t&) && noexcept; + // ditto... +}; +} // toml +``` + +### `at()` + +You can access to the element of a table and an array by `toml::basic_value::at`. + +```cpp +const toml::value v{1,2,3,4,5}; +std::cout << v.at(2).as_integer() << std::endl; // 3 + +const toml::value v{{"foo", 42}, {"bar", 3.14}}; +std::cout << v.at("foo").as_integer() << std::endl; // 42 +``` + +If an invalid key (integer for a table, string for an array), it throws +`toml::type_error` for the conversion. If the provided key is out-of-range, +it throws `std::out_of_range`. + +Note that, although `std::string` has `at()` member function, `toml::value::at` +throws if the contained type is a string. Because `std::string` does not +contain `toml::value`. + +### `operator[]` + +You can also access to the element of a table and an array by +`toml::basic_value::operator[]`. + +```cpp +const toml::value v{1,2,3,4,5}; +std::cout << v[2].as_integer() << std::endl; // 3 + +const toml::value v{{"foo", 42}, {"bar", 3.14}}; +std::cout << v["foo"].as_integer() << std::endl; // 42 +``` + +When you access to a `toml::value` that is not initialized yet via +`operator[](const std::string&)`, the `toml::value` will be a table, +just like the `std::map`. + +```cpp +toml::value v; // not initialized as a table. +v["foo"] = 42; // OK. `v` will be a table. +``` + +Contrary, if you access to a `toml::value` that contains an array via `operator[]`, +it does not check anything. It converts `toml::value` without type check and then +access to the n-th element without boundary check, just like the `std::vector::operator[]`. + +```cpp +toml::value v; // not initialized as an array +v[2] = 42; // error! UB +``` + +Please make sure that the `toml::value` has an array inside when you access to +its element via `operator[]`. + +## Checking value type + +You can check the type of a value by `is_xxx` function. + +```cpp +const toml::value v = /* ... */; +if(v.is_integer()) +{ + std::cout << "value is an integer" << std::endl; +} +``` + +The complete list of the functions is below. + +```cpp +namespace toml { +class value { + // ... + bool is_boolean() const noexcept; + bool is_integer() const noexcept; + bool is_floating() const noexcept; + bool is_string() const noexcept; + bool is_offset_datetime() const noexcept; + bool is_local_datetime() const noexcept; + bool is_local_date() const noexcept; + bool is_local_time() const noexcept; + bool is_array() const noexcept; + bool is_table() const noexcept; + bool is_uninitialized() const noexcept; + // ... +}; +} // toml +``` + +Also, you can get `enum class value_t` from `toml::value::type()`. + +```cpp +switch(data.at("something").type()) +{ + case toml::value_t::integer: /*do some stuff*/ ; break; + case toml::value_t::floating: /*do some stuff*/ ; break; + case toml::value_t::string : /*do some stuff*/ ; break; + default : throw std::runtime_error( + "unexpected type : " + toml::stringize(data.at("something").type())); +} +``` + +The complete list of the `enum`s can be found in the section +[underlying types](#underlying-types). + +The `enum`s can be used as a parameter of `toml::value::is` function like the following. + +```cpp +toml::value v = /* ... */; +if(v.is(toml::value_t::boolean)) // ... +``` + +## More about conversion + +Since `toml::find` internally uses `toml::get`, all the following examples work +with both `toml::get` and `toml::find`. + +### Converting an array + +You can get any kind of `container` class from a `toml::array` +except for `map`-like classes. + +``` cpp +// # sample.toml +// numbers = [1,2,3] + +const auto numbers = toml::find(data, "numbers"); + +const auto vc = toml::get >(numbers); +const auto ls = toml::get >(numbers); +const auto dq = toml::get >(numbers); +const auto ar = toml::get>(numbers); +// if the size of data.at("numbers") is larger than that of std::array, +// it will throw toml::type_error because std::array is not resizable. +``` + +Surprisingly, you can convert `toml::array` into `std::pair` and `std::tuple`. + +```cpp +// numbers = [1,2,3] +const auto tp = toml::get>(numbers); +``` + +This functionality is helpful when you have a toml file like the following. + +```toml +array_of_arrays = [[1, 2, 3], ["foo", "bar", "baz"]] # toml allows this +``` + +What is the corresponding C++ type? +Obviously, it is a `std::pair` of `std::vector`s. + +```cpp +const auto array_of_arrays = toml::find(data, "array_of_arrays"); +const auto aofa = toml::get< + std::pair, std::vector> + >(array_of_arrays); +``` + +If you don't know the type of the elements, you can use `toml::array`, +which is a `std::vector` of `toml::value`, instead. + +```cpp +const auto a_of_a = toml::get(array_of_arrays); +const auto first = toml::get>(a_of_a.at(0)); +``` + +You can change the implementation of `toml::array` with `std::deque` or some +other array-like container. See [Customizing containers](#customizing-containers) +for detail. + +### Converting a table + +When all the values of the table have the same type, toml11 allows you to +convert a `toml::table` to a `map` that contains the convertible type. + +```toml +[tab] +key1 = "foo" # all the values are +key2 = "bar" # toml String +``` + +```cpp +const auto data = toml::parse("sample.toml"); +const auto tab = toml::find>(data, "tab"); +std::cout << tab["key1"] << std::endl; // foo +std::cout << tab["key2"] << std::endl; // bar +``` + +But since `toml::table` is just an alias of `std::unordered_map`, +normally you don't need to convert it because it has all the functionalities that +`std::unordered_map` has (e.g. `operator[]`, `count`, and `find`). In most cases +`toml::table` is sufficient. + +```cpp +toml::table tab = toml::get(data); +if(data.count("title") != 0) +{ + data["title"] = std::string("TOML example"); +} +``` + +You can change the implementation of `toml::table` with `std::map` or some +other map-like container. See [Customizing containers](#customizing-containers) +for detail. + +### Getting an array of tables + +An array of tables is just an array of tables. +You can get it in completely the same way as the other arrays and tables. + +```toml +# sample.toml +array_of_inline_tables = [{key = "value1"}, {key = "value2"}, {key = "value3"}] + +[[array_of_tables]] +key = "value4" +[[array_of_tables]] +key = "value5" +[[array_of_tables]] +key = "value6" +``` + +```cpp +const auto data = toml::parse("sample.toml"); +const auto aot1 = toml::find>(data, "array_of_inline_tables"); +const auto aot2 = toml::find>(data, "array_of_tables"); +``` + +### Cost of conversion + +Although conversion through `toml::(get|find)` is convenient, it has additional +copy-cost because it copies data contained in `toml::value` to the +user-specified type. Of course in some cases this overhead is not ignorable. + +```cpp +// the following code constructs a std::vector. +// it requires heap allocation for vector and element conversion. +const auto array = toml::find>(data, "foo"); +``` + +By passing the exact types, `toml::get` returns reference that has no overhead. + +``` cpp +const auto& tab = toml::find(data, "tab"); +const auto& numbers = toml::find(data, "numbers"); +``` + +Also, `as_xxx` are zero-overhead because they always return a reference. + +``` cpp +const auto& tab = toml::find(data, "tab" ).as_table(); +const auto& numbers = toml::find(data, "numbers").as_array(); +``` + +In this case you need to call `toml::get` each time you access to +the element of `toml::array` because `toml::array` is an array of `toml::value`. + +```cpp +const auto& num0 = toml::get(numbers.at(0)); +const auto& num1 = toml::get(numbers.at(1)); +const auto& num2 = toml::get(numbers.at(2)); +``` + +### Converting datetime and its variants + +TOML v0.5.0 has 4 different datetime objects, `local_date`, `local_time`, +`local_datetime`, and `offset_datetime`. + +Since `local_date`, `local_datetime`, and `offset_datetime` represent a time +point, you can convert them to `std::chrono::system_clock::time_point`. + +Contrary, `local_time` does not represents a time point because they lack a +date information, but it can be converted to `std::chrono::duration` that +represents a duration from the beginning of the day, `00:00:00.000`. + +```toml +# sample.toml +date = 2018-12-23 +time = 12:30:00 +l_dt = 2018-12-23T12:30:00 +o_dt = 2018-12-23T12:30:00+09:30 +``` + +```cpp +const auto data = toml::parse("sample.toml"); + +const auto date = toml::get(data.at("date")); +const auto l_dt = toml::get(data.at("l_dt")); +const auto o_dt = toml::get(data.at("o_dt")); + +const auto time = toml::get(data.at("time")); // 12 * 60 + 30 min +``` + +`local_date` and `local_datetime` are assumed to be in the local timezone when +they are converted into `time_point`. On the other hand, `offset_datetime` only +uses the offset part of the data and it does not take local timezone into account. + +To contain datetime data, toml11 defines its own datetime types. +For more detail, you can see the definitions in [toml/datetime.hpp](toml/datetime.hpp). + +## Getting with a fallback + +`toml::find_or` returns a default value if the value is not found or has a +different type. + +```cpp +const auto data = toml::parse("example.toml"); +const auto num = toml::find_or(data, "num", 42); +``` + +It works recursively if you pass several keys for subtables. +In that case, the last argument is considered to be the optional value. +All other arguments between `toml::value` and the optional value are considered as keys. + +```cpp +// [fruit.physical] +// color = "red" +auto data = toml::parse("fruit.toml"); +auto color = toml::find_or(data, "fruit", "physical", "color", "red"); +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^ +// arguments optional value +``` + +Also, `toml::get_or` returns a default value if `toml::get` failed. + +```cpp +toml::value v("foo"); // v contains String +const int value = toml::get_or(v, 42); // conversion fails. it returns 42. +``` + +These functions automatically deduce what type you want to get +from the default value you passed. + +To get a reference through this function, take care about the default value. + +```cpp +toml::value v("foo"); // v contains String +toml::integer& i = toml::get_or(v, 42); // does not work because binding `42` + // to `integer&` is invalid +toml::integer opt = 42; +toml::integer& i = toml::get_or(v, opt); // this works. +``` + +## Expecting conversion + +By using `toml::expect`, you will get your expected value or an error message +without throwing `toml::type_error`. + +```cpp +const auto value = toml::expect(data.at("title")); +if(value.is_ok()) { + std::cout << value.unwrap() << std::endl; +} else { + std::cout << value.unwrap_err() << std::endl; +} +``` + +Also, you can pass a function object to modify the expected value. + +```cpp +const auto value = toml::expect(data.at("number")) + .map(// function that receives expected type (here, int) + [](const int number) -> double { + return number * 1.5 + 1.0; + }).unwrap_or(/*default value =*/ 3.14); +``` + +## Visiting a toml::value + +toml11 provides `toml::visit` to apply a function to `toml::value` in the +same way as `std::variant`. + +```cpp +const toml::value v(3.14); +toml::visit([](const auto& val) -> void { + std::cout << val << std::endl; + }, v); +``` + +The function object that would be passed to `toml::visit` must be able to +receive all the possible TOML types. Also, the result types should be the same +each other. + +## Constructing a toml::value + +`toml::value` can be constructed in various ways. + +```cpp +toml::value v(true); // boolean +toml::value v(42); // integer +toml::value v(3.14); // floating +toml::value v("foobar"); // string +toml::value v(toml::local_date(2019, toml::month_t::Apr, 1)); // date +toml::value v{1, 2, 3, 4, 5}; // array +toml::value v{{"foo", 42}, {"bar", 3.14}, {"baz", "qux"}}; // table +``` + +When constructing a string, you can choose to use either literal or basic string. +By default, it will be a basic string. + +```cpp +toml::value v("foobar", toml::string_t::basic ); +toml::value v("foobar", toml::string_t::literal); +``` + +Datetime objects can be constructed from `std::tm` and +`std::chrono::system_clock::time_point`. But you need to specify what type +you use to avoid ambiguity. + +```cpp +const auto now = std::chrono::system_clock::now(); +toml::value v(toml::local_date(now)); +toml::value v(toml::local_datetime(now)); +toml::value v(toml::offset_datetime(now)); +``` + +Since local time is not equivalent to a time point, because it lacks date +information, it will be constructed from `std::chrono::duration`. + +```cpp +toml::value v(toml::local_time(std::chrono::hours(10))); +``` + +You can construct an array object not only from `initializer_list`, but also +from STL containers. In that case, the element type must be convertible to +`toml::value`. + +```cpp +std::vector vec{1,2,3,4,5}; +toml::value v(vec); +``` + +When you construct an array value, all the elements of `initializer_list` +must be convertible into `toml::value`. + +If a `toml::value` has an array, you can `push_back` an element in it. + +```cpp +toml::value v{1,2,3,4,5}; +v.push_back(6); +``` + +`emplace_back` also works. + +## Preserving comments + +toml11 v3 or later allows you yo choose whether comments are preserved or not via template parameter + +```cpp +const auto data1 = toml::parse("example.toml"); +const auto data2 = toml::parse("example.toml"); +``` + +or macro definition. + +```cpp +#define TOML11_PRESERVE_COMMENTS_BY_DEFAULT +#include +``` + +This feature is controlled by template parameter in `toml::basic_value<...>`. +`toml::value` is an alias of `toml::basic_value<...>`. + +If template parameter is explicitly specified, the return value of `toml::parse` +will be `toml::basic_value`. +If the macro is defined, the alias `toml::value` will be +`toml::basic_value`. + +Comments related to a value can be obtained by `toml::value::comments()`. +The return value has the same interface as `std::vector`. + +```cpp +const auto& com = v.comments(); +for(const auto& c : com) +{ + std::cout << c << std::endl; +} +``` + +Comments just before and just after (within the same line) a value are kept in a value. + +```toml +# this is a comment for v1. +v1 = "foo" + +v2 = "bar" # this is a comment for v2. +# Note that this comment is NOT a comment for v2. + +# this comment is not related to any value +# because there are empty lines between v3. +# this comment will be ignored even if you set `preserve_comments`. + +# this is a comment for v3 +# this is also a comment for v3. +v3 = "baz" # ditto. +``` + +Each comment line becomes one element of a `std::vector`. + +Hash signs will be removed, but spaces after hash sign will not be removed. + +```cpp +v1.comments().at(0) == " this is a comment for v1."s; + +v2.comments().at(1) == " this is a comment for v1."s; + +v3.comments().at(0) == " this is a comment for v3."s; +v3.comments().at(1) == " this is also a comment for v3."s; +v3.comments().at(2) == " ditto."s; +``` + +Note that a comment just after an opening brace of an array will not be a +comment for the array. + +```toml +# this is a comment for a. +a = [ # this is not a comment for a. this will be ignored. + 1, 2, 3, + # this is a comment for `42`. + 42, # this is also a comment for `42`. + 5 +] # this is a comment for a. +``` + +You can also append and modify comments. +The interfaces are the same as `std::vector`. + +```cpp +toml::basic_value v(42); +v.comments().push_back(" add this comment."); +// # add this comment. +// i = 42 +``` + +Also, you can pass a `std::vector` when constructing a +`toml::basic_value`. + +```cpp +std::vector comments{"comment 1", "comment 2"}; +const toml::basic_value v1(42, std::move(comments)); +const toml::basic_value v2(42, {"comment 1", "comment 2"}); +``` + +When `toml::discard_comments` is chosen, comments will not be contained in a value. +`value::comments()` will always be kept empty. +All the modification on comments would be ignored. +All the element access in a `discard_comments` causes the same error as accessing +an element of an empty `std::vector`. + +The comments will also be serialized. If comments exist, those comments will be +added just before the values. + +__NOTE__: Result types from `toml::parse(...)` and +`toml::parse(...)` are different. + +## Customizing containers + +Actually, `toml::basic_value` has 3 template arguments. + +```cpp +template class Table = std::unordered_map, + template class Array = std::vector> +class basic_value; +``` + +This enables you to change the containers used inside. E.g. you can use +`std::map` to contain a table object instead of `std::unordered_map`. +And also can use `std::deque` as a array object instead of `std::vector`. + +You can set these parameters while calling `toml::parse` function. + +```cpp +const auto data = toml::parse< + toml::preserve_comments, std::map, std::deque + >("example.toml"); +``` + +Needless to say, the result types from `toml::parse(...)` and +`toml::parse(...)` are different (unless you specify the same +types as default). + +Note that, since `toml::table` and `toml::array` is an alias for a table and an +array of a default `toml::value`, so it is different from the types actually +contained in a `toml::basic_value` when you customize containers. +To get the actual type in a generic way, use +`typename toml::basic_type::table_type` and +`typename toml::basic_type::array_type`. + +## TOML literal + +toml11 supports `"..."_toml` literal. +It accept both a bare value and a file content. + +```cpp +using namespace toml::literals::toml_literals; + +// `_toml` can convert a bare value without key +const toml::value v = u8"0xDEADBEEF"_toml; +// v is an Integer value containing 0xDEADBEEF. + +// raw string literal (`R"(...)"` is useful for this purpose) +const toml::value t = u8R"( + title = "this is TOML literal" + [table] + key = "value" +)"_toml; +// the literal will be parsed and the result will be contained in t +``` + +The literal function is defined in the same way as the standard library literals +such as `std::literals::string_literals::operator""s`. + +```cpp +namespace toml +{ +inline namespace literals +{ +inline namespace toml_literals +{ +toml::value operator"" _toml(const char* str, std::size_t len); +} // toml_literals +} // literals +} // toml +``` + +Access to the operator can be gained with `using namespace toml::literals;`, +`using namespace toml::toml_literals`, and `using namespace toml::literals::toml_literals`. + +Note that a key that is composed only of digits is allowed in TOML. +And, unlike the file parser, toml-literal allows a bare value without a key. +Thus it is difficult to distinguish arrays having integers and definitions of +tables that are named as digits. +Currently, literal `[1]` becomes a table named "1". +To ensure a literal to be considered as an array with one element, you need to +add a comma after the first element (like `[1,]`). + +```cpp +"[1,2,3]"_toml; // This is an array +"[table]"_toml; // This is a table that has an empty table named "table" inside. +"[[1,2,3]]"_toml; // This is an array of arrays +"[[table]]"_toml; // This is a table that has an array of tables inside. + +"[[1]]"_toml; // This literal is ambiguous. + // Currently, it becomes an empty array of table named "1". +"1 = [{}]"_toml; // This is a table that has an array of table named 1. +"[[1,]]"_toml; // This is an array of arrays. +"[[1],]"_toml; // ditto. +``` + +NOTE: `_toml` literal returns a `toml::value` that does not have comments. + +## Conversion between toml value and arbitrary types + +You can also use `toml::get` and other related functions with the types +you defined after you implement a way to convert it. + +```cpp +namespace ext +{ +struct foo +{ + int a; + double b; + std::string c; +}; +} // ext + +const auto data = toml::parse("example.toml"); + +// to do this +const foo f = toml::find(data, "foo"); +``` + +There are 3 ways to use `toml::get` with the types that you defined. + +The first one is to implement `from_toml(const toml::value&)` member function. + +```cpp +namespace ext +{ +struct foo +{ + int a; + double b; + std::string c; + + void from_toml(const toml::value& v) + { + this->a = toml::find(v, "a"); + this->b = toml::find(v, "b"); + this->c = toml::find(v, "c"); + return; + } +}; +} // ext +``` + +In this way, because `toml::get` first constructs `foo` without arguments, +the type should be default-constructible. + +The second is to implement `constructor(const toml::value&)`. + +```cpp +namespace ext +{ +struct foo +{ + explicit foo(const toml::value& v) + : a(toml::find(v, "a")), b(toml::find(v, "b")), + c(toml::find(v, "c")) + {} + + int a; + double b; + std::string c; +}; +} // ext +``` + +Note that implicit default constructor declaration will be suppressed +when a constructor is defined. If you want to use the struct (here, `foo`) +in a container (e.g. `std::vector`), you may need to define default +constructor explicitly. + +The third is to implement specialization of `toml::from` for your type. + +```cpp +namespace ext +{ +struct foo +{ + int a; + double b; + std::string c; +}; +} // ext + +namespace toml +{ +template<> +struct from +{ + static ext::foo from_toml(const value& v) + { + ext::foo f; + f.a = find(v, "a"); + f.b = find(v, "b"); + f.c = find(v, "c"); + return f; + } +}; +} // toml +``` + +In this way, since the conversion function is defined outside of the class, +you can add conversion between `toml::value` and classes defined in another library. + +In some cases, a class has a templatized constructor that takes a template, `T`. +It confuses `toml::get/find` because it makes the class "constructible" from +`toml::value`. To avoid this problem, `toml::from` and `from_toml` always +precede constructor. It makes easier to implement conversion between +`toml::value` and types defined in other libraries because it skips constructor. + +But, importantly, you cannot define `toml::from` and `T.from_toml` at the same +time because it causes ambiguity in the overload resolution of `toml::get` and `toml::find`. + +So the precedence is `toml::from` == `T.from_toml()` > `T(toml::value)`. + +If you want to convert any versions of `toml::basic_value`, +you need to templatize the conversion function as follows. + +```cpp +struct foo +{ + template class M, template class A> + void from_toml(const toml::basic_value& v) + { + this->a = toml::find(v, "a"); + this->b = toml::find(v, "b"); + this->c = toml::find(v, "c"); + return; + } +}; +// or +namespace toml +{ +template<> +struct from +{ + template class M, template class A> + static ext::foo from_toml(const basic_value& v) + { + ext::foo f; + f.a = find(v, "a"); + f.b = find(v, "b"); + f.c = find(v, "c"); + return f; + } +}; +} // toml +``` + +---- + +The opposite direction is also supported in a similar way. You can directly +pass your type to `toml::value`'s constructor by introducing `into_toml` or +`toml::into`. + +```cpp +namespace ext +{ +struct foo +{ + int a; + double b; + std::string c; + + toml::value into_toml() const // you need to mark it const. + { + return toml::value{{"a", this->a}, {"b", this->b}, {"c", this->c}}; + } +}; +} // ext + +ext::foo f{42, 3.14, "foobar"}; +toml::value v(f); +``` + +The definition of `toml::into` is similar to `toml::from`. + +```cpp +namespace ext +{ +struct foo +{ + int a; + double b; + std::string c; +}; +} // ext + +namespace toml +{ +template<> +struct into +{ + static toml::value into_toml(const ext::foo& f) + { + return toml::value{{"a", f.a}, {"b", f.b}, {"c", f.c}}; + } +}; +} // toml + +ext::foo f{42, 3.14, "foobar"}; +toml::value v(f); +``` + +Any type that can be converted to `toml::value`, e.g. `int`, `toml::table` and +`toml::array` are okay to return from `into_toml`. + +You can also return a custom `toml::basic_value` from `toml::into`. + +```cpp +namespace toml +{ +template<> +struct into +{ + static toml::basic_value into_toml(const ext::foo& f) + { + toml::basic_value v{{"a", f.a}, {"b", f.b}, {"c", f.c}}; + v.comments().push_back(" comment"); + return v; + } +}; +} // toml +``` + +But note that, if this `basic_value` would be assigned into other `toml::value` +that discards `comments`, the comments would be dropped. + +### Macro to automatically define conversion functions + +There is a helper macro that automatically generates conversion functions `from` and `into` for a simple struct. + +```cpp +namespace foo +{ +struct Foo +{ + std::string s; + double d; + int i; +}; +} // foo + +TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(foo::Foo, s, d, i) + +int main() +{ + const auto file = toml::parse("example.toml"); + auto f = toml::find(file, "foo"); +} +``` + +And then you can use `toml::find(file, "foo");` + +**Note** that, because of a slight difference in implementation of preprocessor between gcc/clang and MSVC, [you need to define `/Zc:preprocessor`](https://github.com/ToruNiina/toml11/issues/139#issuecomment-803683682) to use it in MSVC (Thank you @glebm !). + +## Formatting user-defined error messages + +When you encounter an error after you read the toml value, you may want to +show the error with the value. + +toml11 provides you a function that formats user-defined error message with +related values. With a code like the following, + +```cpp +const auto value = toml::find(data, "num"); +if(value < 0) +{ + std::cerr << toml::format_error("[error] value should be positive", + data.at("num"), "positive number required") + << std::endl; +} +``` + +you will get an error message like this. + +```console +[error] value should be positive + --> example.toml + 3 | num = -42 + | ~~~ positive number required +``` + +When you pass two values to `toml::format_error`, + +```cpp +const auto min = toml::find(range, "min"); +const auto max = toml::find(range, "max"); +if(max < min) +{ + std::cerr << toml::format_error("[error] max should be larger than min", + data.at("min"), "minimum number here", + data.at("max"), "maximum number here"); + << std::endl; +} +``` + +you will get an error message like this. + +```console +[error] max should be larger than min + --> example.toml + 3 | min = 54 + | ~~ minimum number here + ... + 4 | max = 42 + | ~~ maximum number here +``` + +You can print hints at the end of the message. + +```cpp +std::vector hints; +hints.push_back("positive number means n >= 0."); +hints.push_back("negative number is not positive."); +std::cerr << toml::format_error("[error] value should be positive", + data.at("num"), "positive number required", hints) + << std::endl; +``` + +```console +[error] value should be positive + --> example.toml + 2 | num = 42 + | ~~ positive number required + | +Hint: positive number means n >= 0. +Hint: negative number is not positive. +``` + +## Obtaining location information + +You can also format error messages in your own way by using `source_location`. + +```cpp +struct source_location +{ + std::uint_least32_t line() const noexcept; + std::uint_least32_t column() const noexcept; + std::uint_least32_t region() const noexcept; + std::string const& file_name() const noexcept; + std::string const& line_str() const noexcept; +}; +// +-- line() +--- length of the region (here, region() == 9) +// v .---+---. +// 12 | value = "foo bar" <- line_str() returns the line itself. +// ^-------- column() points here +``` + +You can get this by +```cpp +const toml::value v = /*...*/; +const toml::source_location loc = v.location(); +``` + +## Exceptions + +The following `exception` classes inherits `toml::exception` that inherits +`std::exception`. + +```cpp +namespace toml { +struct exception : public std::exception {/**/}; +struct syntax_error : public toml::exception {/**/}; +struct type_error : public toml::exception {/**/}; +struct internal_error : public toml::exception {/**/}; +} // toml +``` + +`toml::exception` has `toml::exception::location()` member function that returns +`toml::source_location`, in addition to `what()`. + +```cpp +namespace toml { +struct exception : public std::exception +{ + // ... + source_location const& location() const noexcept; +}; +} // toml +``` + +It represents where the error occurs. + +`syntax_error` will be thrown from `toml::parse` and `_toml` literal. +`type_error` will be thrown from `toml::get/find`, `toml::value::as_xxx()`, and +other functions that takes a content inside of `toml::value`. + +Note that, currently, from `toml::value::at()` and `toml::find(value, key)` +may throw an `std::out_of_range` that does not inherits `toml::exception`. + +Also, in some cases, most likely in the file open error, it will throw an +`std::runtime_error`. + +## Colorize Error Messages + +By defining `TOML11_COLORIZE_ERROR_MESSAGE`, the error messages from +`toml::parse` and `toml::find|get` will be colorized. By default, this feature +is turned off. + +With the following toml file taken from `toml-lang/toml/tests/hard_example.toml`, + +```toml +[error] +array = [ + "This might most likely happen in multiline arrays", + Like here, + "or here, + and here" + ] End of array comment, forgot the # +``` + +the error message would be like this. + +![error-message-1](https://github.com/ToruNiina/toml11/blob/misc/misc/toml11-err-msg-1.png) + +With the following, + +```toml +[error] +# array = [ +# "This might most likely happen in multiline arrays", +# Like here, +# "or here, +# and here" +# ] End of array comment, forgot the # +number = 3.14 pi <--again forgot the # +``` + +the error message would be like this. + +![error-message-2](https://github.com/ToruNiina/toml11/blob/misc/misc/toml11-err-msg-2.png) + +The message would be messy when it is written to a file, not a terminal because +it uses [ANSI escape code](https://en.wikipedia.org/wiki/ANSI_escape_code). + +Without `TOML11_COLORIZE_ERROR_MESSAGE`, you can still colorize user-defined +error message by passing `true` to the `toml::format_error` function. +If you define `TOML11_COLORIZE_ERROR_MESSAGE`, the value is `true` by default. +If not, the default value would be `false`. + +```cpp +std::cerr << toml::format_error("[error] value should be positive", + data.at("num"), "positive number required", + hints, /*colorize = */ true) << std::endl; +``` + +Note: It colorizes `[error]` in red. That means that it detects `[error]` prefix +at the front of the error message. If there is no `[error]` prefix, +`format_error` adds it to the error message. + +Compared to the `TOML11_COLORIZE_ERROR_MESSAGE` macro that enables colorization +statically, toml11 provides `toml::color::enable` & `toml::color::disable` +functions to dynamically change the color mode. This feature overwrites +`TOML11_COLORIZE_ERROR_MESSAGE` and the `colorize` argument of +`toml::format_error` when you call `enable`. + +Note: If either `TOML11_COLORIZE_ERROR_MESSAGE` is defined or the `colorize` +argument is used, it takes precedence, meaning that `disable` won't work. +Accordingly, we highly recommend using only one of them. + +```cpp +toml::color::enable(); // enable colorization +toml::color::disable(); // disable colorization +``` + +If you use user-defined error message, you can manage the setting as follows: + +```cpp +toml::color::enable(); +std::cerr << toml::format_error("[error] value should be positive", + data.at("num"), "positive number required", + hints) << std::endl; // colorized + +toml::color::disable(); +std::cerr << toml::format_error("[error] value should be positive", + data.at("num"), "positive number required", + hints) << std::endl; // NOT colorized +``` + +Or you may use toml11 in your application like: + +```cpp +std::vector args(argv + 1, argv + argc); +auto result = std::find(args.begin(), args.end(), "--color"); +if (result != args.end()) { + toml::color::enable(); +} else { + toml::color::disable(); +} + +// use toml11 ... +``` + +## Opting out of the default `[error]` prefix + +toml11 prints error messages with the `[error]` prefix by default. +Defining `TOML11_NO_ERROR_PREFIX` will let toml11 omit the prefix regardless of colorized or not in case you would use a custom prefix, such as `Error:`. + +```cpp +#define TOML11_NO_ERROR_PREFIX +``` + +## Serializing TOML data + +toml11 enables you to serialize data into toml format. + +```cpp +const toml::value data{{"foo", 42}, {"bar", "baz"}}; +std::cout << data << std::endl; +// bar = "baz" +// foo = 42 +``` + +toml11 automatically makes a small table and small array inline. +You can specify the width to make them inline by `std::setw` for streams. + +```cpp +const toml::value data{ + {"qux", {{"foo", 42}, {"bar", "baz"}}}, + {"quux", {"small", "array", "of", "strings"}}, + {"foobar", {"this", "array", "of", "strings", "is", "too", "long", + "to", "print", "into", "single", "line", "isn't", "it?"}}, +}; + +// the threshold becomes 80. +std::cout << std::setw(80) << data << std::endl; +// foobar = [ +// "this","array","of","strings","is","too","long","to","print","into", +// "single","line","isn't","it?", +// ] +// quux = ["small","array","of","strings"] +// qux = {bar="baz",foo=42} + + +// the width is 0. nothing become inline. +std::cout << std::setw(0) << data << std::endl; +// foobar = [ +// "this", +// ... (snip) +// "it?", +// ] +// quux = [ +// "small", +// "array", +// "of", +// "strings", +// ] +// [qux] +// bar = "baz" +// foo = 42 +``` + +It is recommended to set width before printing data. Some I/O functions changes +width to 0, and it makes all the stuff (including `toml::array`) multiline. +The resulting files becomes too long. + +To control the precision of floating point numbers, you need to pass +`std::setprecision` to stream. + +```cpp +const toml::value data{ + {"pi", 3.141592653589793}, + {"e", 2.718281828459045} +}; +std::cout << std::setprecision(17) << data << std::endl; +// e = 2.7182818284590451 +// pi = 3.1415926535897931 +std::cout << std::setprecision( 7) << data << std::endl; +// e = 2.718282 +// pi = 3.141593 +``` + +There is another way to format toml values, `toml::format()`. +It returns `std::string` that represents a value. + +```cpp +const toml::value v{{"a", 42}}; +const std::string fmt = toml::format(v); +// a = 42 +``` + +Note that since `toml::format` formats a value, the resulting string may lack +the key value. + +```cpp +const toml::value v{3.14}; +const std::string fmt = toml::format(v); +// 3.14 +``` + +To control the width and precision, `toml::format` receives optional second and +third arguments to set them. By default, the width is 80 and the precision is +`std::numeric_limits::max_digit10`. + +```cpp +const auto serial = toml::format(data, /*width = */ 0, /*prec = */ 17); +``` + +When you pass a comment-preserving-value, the comment will also be serialized. +An array or a table containing a value that has a comment would not be inlined. + +## Underlying types + +The toml types (can be used as `toml::*` in this library) and corresponding `enum` names are listed in the table below. + +| TOML type | underlying c++ type | enum class | +| -------------- | ---------------------------------- | -------------------------------- | +| Boolean | `bool` | `toml::value_t::boolean` | +| Integer | `std::int64_t` | `toml::value_t::integer` | +| Float | `double` | `toml::value_t::floating` | +| String | `toml::string` | `toml::value_t::string` | +| LocalDate | `toml::local_date` | `toml::value_t::local_date` | +| LocalTime | `toml::local_time` | `toml::value_t::local_time` | +| LocalDatetime | `toml::local_datetime` | `toml::value_t::local_datetime` | +| OffsetDatetime | `toml::offset_datetime` | `toml::value_t::offset_datetime` | +| Array | `array-like` | `toml::value_t::array` | +| Table | `map-like` | `toml::value_t::table` | + +`array-like` and `map-like` are the STL containers that works like a `std::vector` and +`std::unordered_map`, respectively. By default, `std::vector` and `std::unordered_map` +are used. See [Customizing containers](#customizing-containers) for detail. + +`toml::string` is effectively the same as `std::string` but has an additional +flag that represents a kind of a string, `string_t::basic` and `string_t::literal`. +Although `std::string` is not an exact toml type, still you can get a reference +that points to internal `std::string` by using `toml::get()` for convenience. +The most important difference between `std::string` and `toml::string` is that +`toml::string` will be formatted as a TOML string when outputted with `ostream`. +This feature is introduced to make it easy to write a custom serializer. + +`Datetime` variants are `struct` that are defined in this library. +Because `std::chrono::system_clock::time_point` is a __time point__, +not capable of representing a Local Time independent from a specific day. + +## Unreleased TOML features + +After TOML v1.0.0 has been released, some features are added to the main branch +of the TOML spec repository. (see: [CHANGELOG.md in toml-lang/toml repository](https://github.com/toml-lang/toml/blob/main/CHANGELOG.md)). + +The following list shows available "unreleased" features that can be activated +by defining a macro named `TOML11_USE_UNRELEASED_FEATURES`. + +- Add new `\e` shorthand for the escape character. + +## Note about heterogeneous arrays + +Although `toml::parse` allows heterogeneous arrays, constructor of `toml::value` +does not. Here the reason is explained. + +```cpp +// this won't be compiled +toml::value v{ + "foo", 3.14, 42, {1,2,3,4,5}, {{"key", "value"}} +} +``` + +There is a workaround for this. By explicitly converting values into +`toml::value`, you can initialize `toml::value` with a heterogeneous array. +Also, you can first initialize a `toml::value` with an array and then +`push_back` into it. + +```cpp +// OK! +toml::value v{ + toml::value("foo"), toml::value(3.14), toml::value(42), + toml::value{1,2,3,4,5}, toml::value{{"key", "value"}} +} + +// OK! +toml::value v(toml::array{}); +v.push_back("foo"); +v.push_back(3.14); + +// OK! +toml::array a; +a.push_back("foo"); +a.push_back(3.14); +toml::value v(std::move(a)); +``` + +The reason why the first example is not allowed is the following. +Let's assume that you are initializing a `toml::value` with a table. + +```cpp + // # expecting TOML table. +toml::value v{ // [v] + {"answer", 42}, // answer = 42 + {"pi", 3.14}, // pi = 3.14 + {"foo", "bar"} // foo = "bar" +}; +``` + +This is indistinguishable from a (heterogeneous) TOML array definition. + +```toml +v = [ + ["answer", 42], + ["pi", 3.14], + ["foo", "bar"], +] +``` + +This means that the above C++ code makes constructor's overload resolution +ambiguous. So a constructor that allows both "table as an initializer-list" and +"heterogeneous array as an initializer-list" cannot be implemented. + +Thus, although it is painful, we need to explicitly cast values into +`toml::value` when you initialize heterogeneous array in a C++ code. + +```cpp +toml::value v{ + toml::value("foo"), toml::value(3.14), toml::value(42), + toml::value{1,2,3,4,5}, toml::value{{"key", "value"}} +}; +``` + +## Breaking Changes from v2 + +Although toml11 is relatively new library (it's three years old now), it had +some confusing and inconvenient user-interfaces because of historical reasons. + +Between v2 and v3, those interfaces are rearranged. + +- `toml::parse` now returns a `toml::value`, not `toml::table`. +- `toml::value` is now an alias of `toml::basic_value`. + - See [Customizing containers](#customizing-containers) for detail. +- The elements of `toml::value_t` are renamed as `snake_case`. + - See [Underlying types](#underlying-types) for detail. +- Supports for the CamelCaseNames are dropped. + - See [Underlying types](#underlying-types) for detail. +- `(is|as)_float` has been removed to make the function names consistent with others. + - Since `float` is a keyword, toml11 named a float type as `toml::floating`. + - Also a `value_t` corresponds to `toml::floating` is named `value_t::floating`. + - So `(is|as)_floating` is introduced and `is_float` has been removed. + - See [Casting a toml::value](#casting-a-tomlvalue) and [Checking value type](#checking-value-type) for detail. +- An overload of `toml::find` for `toml::table` has been dropped. Use `toml::value` version instead. + - Because type conversion between a table and a value causes ambiguity while overload resolution + - Since `toml::parse` now returns a `toml::value`, this feature becomes less important. + - Also because `toml::table` is a normal STL container, implementing utility function is easy. + - See [Finding a toml::value](#finding-a-toml-value) for detail. +- An overload of `operator<<` and `toml::format` for `toml::table`s are dropped. + - Use `toml::value` instead. + - See [Serializing TOML data](#serializing-toml-data) for detail. +- Interface around comments. + - See [Preserving Comments](#preserving-comments) for detail. +- An ancient `from_toml/into_toml` has been removed. Use arbitrary type conversion support. + - See [Conversion between toml value and arbitrary types](#conversion-between-toml-value-and-arbitrary-types) for detail. + +Such a big change will not happen in the coming years. + +## Running Tests + +After cloning this repository, run the following command (thank you @jwillikers +for automating test set fetching!). + +```sh +$ mkdir build +$ cd build +$ cmake .. -Dtoml11_BUILD_TEST=ON +$ make +$ make test +``` + +To run the language agnostic test suite, you need to compile +`tests/check_toml_test.cpp` and pass it to the tester. + +## Contributors + +I appreciate the help of the contributors who introduced the great feature to this library. + +- Guillaume Fraux (@Luthaf) + - Windows support and CI on Appvayor + - Intel Compiler support +- Quentin Khan (@xaxousis) + - Found & Fixed a bug around ODR + - Improved error messages for invalid keys to show the location where the parser fails +- Petr Beneš (@wbenny) + - Fixed warnings on MSVC +- Ivan Shynkarenka (@chronoxor) + - Fixed Visual Studio 2019 warnings + - Fix compilation error in `` with MinGW +- Khoi Dinh Trinh (@khoitd1997) + - Fixed warnings while type conversion +- @KerstinKeller + - Added installation script to CMake +- J.C. Moyer (@jcmoyer) + - Fixed an example code in the documentation +- Jt Freeman (@blockparty-sh) + - Fixed feature test macro around `localtime_s` + - Suppress warnings in Debug mode +- OGAWA Kenichi (@kenichiice) + - Suppress warnings on intel compiler + - Fix include path in README +- Jordan Williams (@jwillikers) + - Fixed clang range-loop-analysis warnings + - Fixed feature test macro to suppress -Wundef + - Use cache variables in CMakeLists.txt + - Automate test set fetching, update and refactor CMakeLists.txt +- Scott McCaskill + - Parse 9 digits (nanoseconds) of fractional seconds in a `local_time` +- Shu Wang (@halfelf) + - fix "Finding a value in an array" example in README +- @maass-tv and @SeverinLeonhardt + - Fix MSVC warning C4866 +- Mohammed Alyousef (@MoAlyousef) + - Made testing optional in CMake +- Alex Merry (@amerry) + - Add missing include files +- sneakypete81 (@sneakypete81) + - Fix typo in error message +- Oliver Kahrmann (@founderio) + - Fix missing filename in error message if parsed file is empty +- Karl Nilsson (@karl-nilsson) + - Fix many spelling errors +- ohdarling88 (@ohdarling) + - Fix a bug in a constructor of serializer +- estshorter (@estshorter) + - Fix MSVC warning C26478 +- Philip Top (@phlptp) + - Improve checking standard library feature availability check +- Louis Marascio (@marascio) + - Fix free-nonheap-object warning +- Axel Huebl (@ax3l) + - Make installation optional if the library is embedded +- Ken Matsui (@ken-matsui) + - Support user-defined error message prefix + - Support dynamic color mode +- Giel van Schijndel (@muggenhor) + - Remove needless copy in `parse` function +- Lukáš Hrázký (@lukash) + - Add a `parse(FILE *)` interface and improve file-related error messages +- spiderman idog (@spiderman-idog) + - Fix typo in README +- Jajauma's GitHub (@Jajauma) + - Avoid possible lexer truncation warnings +- Moritz Klammler (@ctcmkl) + - Many patches in (#200) including: + - Improve CMake scripts, build process, and test file handling + - Detect error when `discard_comments` is accessed + - And more. +- Chris White (@cxw42) + - Fix address-sanitizer error when parsing literal strings having invalid UTF-8 characters + - Fix function name in error messages +- offa (@offa) + - Update checkout action to v3 + - Update Required CMake version + - Cleanup old CI settings +- Sergey Vidyuk (@VestniK) + - Fix for case when vector iterator is raw pointer +- Kfir Gollan (@kfirgollan) + - Add installation example with checkinstall and cmake +- Martin Tournoij (@arp242) + - Escape control characters in keys +- @DavidKorczynski + - Add fuzzing test based on ClusterFuzzLite +- Esonhugh Skyworship (@Esonhugh) + - Fix function signature of `strerror_r` on macos + +## Licensing terms + +This product is licensed under the terms of the [MIT License](LICENSE). + +- Copyright (c) 2017-2024 Toru Niina + +All rights reserved. diff --git a/external/toml11/appveyor.yml b/external/toml11/appveyor.yml new file mode 100644 index 0000000..3871566 --- /dev/null +++ b/external/toml11/appveyor.yml @@ -0,0 +1,25 @@ +version: "{build}" +os: Visual Studio 2015 + +environment: + matrix: + - generator: Visual Studio 14 2015 Win64 + - generator: Visual Studio 14 2015 + +configuration: + - Release + - Debug + +clone_depth: 10 +clone_folder: c:\toml11 + +build_script: + - cd C:\toml11 + - mkdir build + - cd build + - cmake -G"%generator%" -DCMAKE_CXX_STANDARD=11 -DBOOST_ROOT=C:/Libraries/boost_1_69_0 -Dtoml11_BUILD_TEST=ON .. + - cmake --build . --config "%configuration%" + - file --mime-encoding tests/toml/tests/hard_example_unicode.toml + +test_script: + - ctest --build-config "%configuration%" --timeout 300 --output-on-failure diff --git a/external/toml11/cmake/toml11Config.cmake.in b/external/toml11/cmake/toml11Config.cmake.in new file mode 100644 index 0000000..edc73f6 --- /dev/null +++ b/external/toml11/cmake/toml11Config.cmake.in @@ -0,0 +1,2 @@ +@PACKAGE_INIT@ +include("@PACKAGE_toml11_install_cmake_dir@/toml11Targets.cmake") diff --git a/external/toml11/tests/CMakeLists.txt b/external/toml11/tests/CMakeLists.txt new file mode 100644 index 0000000..332eaa8 --- /dev/null +++ b/external/toml11/tests/CMakeLists.txt @@ -0,0 +1,291 @@ +include(ExternalProject) + +set(TOML11_LANGSPEC_GIT_REPOSITORY "https://github.com/toml-lang/toml" CACHE STRING + "URL of the TOML language specification repository") + +set(TOML11_LANGSPEC_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/toml" CACHE FILEPATH + "directory for the TOML language specification tree") + +if(NOT EXISTS "${TOML11_LANGSPEC_SOURCE_DIR}/toml.abnf") + ExternalProject_Add(toml + SOURCE_DIR "${TOML11_LANGSPEC_SOURCE_DIR}" + GIT_REPOSITORY "${TOML11_LANGSPEC_GIT_REPOSITORY}" + GIT_TAG "v0.5.0" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "") +endif() + +set(TEST_NAMES + test_datetime + test_string + test_utility + test_result + test_traits + test_value + test_lex_boolean + test_lex_integer + test_lex_floating + test_lex_datetime + test_lex_string + test_lex_key_comment + test_parse_boolean + test_parse_integer + test_parse_floating + test_parse_string + test_parse_datetime + test_parse_array + test_parse_table + test_parse_inline_table + test_parse_key + test_parse_table_key + test_literals + test_comments + test_get + test_get_or + test_find + test_find_or + test_find_or_recursive + test_expect + test_parse_file + test_serialize_file + test_parse_unicode + test_error_detection + test_format_error + test_extended_conversions +) + +CHECK_CXX_COMPILER_FLAG("-Wall" COMPILER_SUPPORTS_WALL) +CHECK_CXX_COMPILER_FLAG("-Wextra" COMPILER_SUPPORTS_WEXTRA) +CHECK_CXX_COMPILER_FLAG("-Wpedantic" COMPILER_SUPPORTS_WPEDANTIC) +CHECK_CXX_COMPILER_FLAG("-Werror" COMPILER_SUPPORTS_WERROR) + +CHECK_CXX_COMPILER_FLAG("-Wsign-conversion" COMPILER_SUPPORTS_WSIGN_CONVERSION) +CHECK_CXX_COMPILER_FLAG("-Wconversion" COMPILER_SUPPORTS_WCONVERSION) +CHECK_CXX_COMPILER_FLAG("-Wduplicated-cond" COMPILER_SUPPORTS_WDUPLICATED_COND) +CHECK_CXX_COMPILER_FLAG("-Wduplicated-branches" COMPILER_SUPPORTS_WDUPLICATED_BRANCHES) +CHECK_CXX_COMPILER_FLAG("-Wlogical-op" COMPILER_SUPPORTS_WLOGICAL_OP) +CHECK_CXX_COMPILER_FLAG("-Wuseless-cast" COMPILER_SUPPORTS_WUSELESS_CAST) +CHECK_CXX_COMPILER_FLAG("-Wdouble-promotion" COMPILER_SUPPORTS_WDOUBLE_PROMOTION) +CHECK_CXX_COMPILER_FLAG("-Wrange-loop-analysis" COMPILER_SUPPORTS_WRANGE_LOOP_ANALYSIS) +CHECK_CXX_COMPILER_FLAG("-Wundef" COMPILER_SUPPORTS_WUNDEF) +CHECK_CXX_COMPILER_FLAG("-Wshadow" COMPILER_SUPPORTS_WSHADOW) + +include(CheckCXXSourceCompiles) + +# check which standard library implementation is used. If libstdc++ is used, +# it will fail to compile. It compiles if libc++ is used. +check_cxx_source_compiles(" +#include +#ifdef __GLIBCXX__ + static_assert(false); +#endif +int main() { + return 0; +}" TOML11_WITH_LIBCXX_LIBRARY) + +# LLVM 8 requires -lc++fs if compiled with libc++ to use . +# LLVM 9+ does not require any special library. +# GCC 8 requires -lstdc++fs. GCC 9+ does not require it. +# +# Yes, we can check the version of the compiler used in the current build +# directly in CMake. But, in most cases, clang build uses libstdc++ as the +# standard library implementation and it makes the condition complicated. +# In many environment, the default installed C++ compiler is GCC and libstdc++ +# is installed along with it. In most build on such an environment, even if we +# chose clang as the C++ compiler, still libstdc++ is used. Checking default +# gcc version makes the condition complicated. +# The purpose of this file is to compile tests. We know the environment on which +# the tests run. We can set this option and, I think, it is easier and better. +option(TOML11_REQUIRE_FILESYSTEM_LIBRARY "need to link -lstdc++fs or -lc++fs" OFF) + +find_package(Boost COMPONENTS unit_test_framework REQUIRED) + +set(PREVIOUSLY_REQUIRED_INCLUDES "${CMAKE_REQUIRED_INCLUDES}") +set(PREVIOUSLY_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + +list(APPEND CMAKE_REQUIRED_INCLUDES ${Boost_INCLUDE_DIRS}) +list(APPEND CMAKE_REQUIRED_LIBRARIES ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) + +check_cxx_source_compiles(" +#define BOOST_TEST_MODULE \"dummy\" +#undef BOOST_TEST_DYN_LINK +#define BOOST_TEST_NO_LIB +#include +BOOST_AUTO_TEST_CASE(proforma) { BOOST_TEST(true); } +" TOML11_WITH_BOOST_TEST_HEADER) + +check_cxx_source_compiles(" +#define BOOST_TEST_MODULE \"dummy\" +#undef BOOST_TEST_DYN_LINK +#undef BOOST_TEST_NO_LIB +#include +BOOST_AUTO_TEST_CASE(proforma) { BOOST_TEST(true); } +" TOML11_WITH_BOOST_TEST_STATIC) + +check_cxx_source_compiles(" +#define BOOST_TEST_MODULE \"dummy\" +#define BOOST_TEST_DYN_LINK +#undef BOOST_TEST_NO_LIB +#include +BOOST_AUTO_TEST_CASE(proforma) { BOOST_TEST(true); } +" TOML11_WITH_BOOST_TEST_DYNAMIC) + +set(CMAKE_REQUIRED_INCLUDES "${PREVIOUSLY_REQUIRED_INCLUDES}") +set(CMAKE_REQUIRED_LIBRARIES "${PREVIOUSLY_REQUIRED_LIBRARIES}") + +unset(PREVIOUSLY_REQUIRED_INCLUDES) +unset(PREVIOUSLY_REQUIRED_LIBRARIES) + +if(TOML11_WITH_BOOST_TEST_DYNAMIC) + add_definitions(-DUNITTEST_FRAMEWORK_LIBRARY_EXIST -DBOOST_TEST_DYN_LINK) +elseif(TOML11_WITH_BOOST_TEST_STATIC) + add_definitions(-DUNITTEST_FRAMEWORK_LIBRARY_EXIST) +elseif(TOML11_WITH_BOOST_TEST_HEADER) + add_definitions(-DBOOST_TEST_NO_LIB) +else() + message(FATAL_ERROR "Neither the Boost.Test static or shared library nor the header-only version seem to be usable.") +endif() + +if(COMPILER_SUPPORTS_WALL) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") +endif() +if(COMPILER_SUPPORTS_WEXTRA) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra") +endif() +if(COMPILER_SUPPORTS_WPEDANTIC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic") +endif() +if(COMPILER_SUPPORTS_WERROR) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") +endif() +if(COMPILER_SUPPORTS_WSHADOW) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wshadow") +endif() +if(COMPILER_SUPPORTS_WSIGN_CONVERSION) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsign-conversion") +endif() +if(COMPILER_SUPPORTS_WCONVERSION) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wconversion") +endif() +if(COMPILER_SUPPORTS_WDUPLICATED_COND) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wduplicated-cond") +endif() +if(COMPILER_SUPPORTS_WDUPLICATED_BRANCHES) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wduplicated-branches") +endif() +if(COMPILER_SUPPORTS_WLOGICAL_OP) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wlogical-op") +endif() +if(COMPILER_SUPPORTS_WUSELESS_CAST) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wuseless-cast") +endif() +if(COMPILER_SUPPORTS_WDOUBLE_PROMOTION) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wdouble-promotion") +endif() +if(COMPILER_SUPPORTS_WRANGE_LOOP_ANALYSIS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wrange-loop-analysis") +endif() +if(COMPILER_SUPPORTS_WUNDEF) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wundef") +endif() + +if(TOML11_USE_UNRELEASED_TOML_FEATURES) + message(STATUS "adding TOML11_USE_UNRELEASED_TOML_FEATURES flag") + add_definitions("-DTOML11_USE_UNRELEASED_TOML_FEATURES") +endif() + +# Disable some MSVC warnings +if(MSVC) + # conversion from 'double' to 'unsigned int', possible loss of data + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244") + # conversion from 'int' to 'unsigned int', signed/unsigned mismatch + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4365") + # layout of class may have changed from a previous version of the compiler + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4371") + # enumerator in switch of enum is not explicitly handled by a case label + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4061") + # unreferenced inline function has been removed + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4514") + # constructor is not implicitly called + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4582") + # destructor is not implicitly called + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4583") + # pragma warning: there is no warning number + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4619") + # default constructor was implicitly defined as deleted + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4623") + # copy constructor was implicitly defined as deleted + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4625") + # assignment operator was implicitly defined as deleted + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4626") + # move assignment operator was implicitly defined as deleted + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4627") + # is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4668") + # function not inlined + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4710") + # function selected for automatic inlining + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4711") + # bytes padding added after data member + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4820") + # pragma warning(pop): likely mismatch, popping warning state pushed in different file + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd5031") + # pragma warning(pop): spectre warnings in tests + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd5045") + # pragma warning(pop): spectre warnings in tests + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4265") +endif() + +set(TEST_ENVIRON "TOMLDIR=${TOML11_LANGSPEC_SOURCE_DIR}") +if(WIN32) + # Set the PATH to be able to find Boost DLL + STRING(REPLACE ";" "\\;" PATH_STRING "$ENV{PATH}") + list(APPEND TEST_ENVIRON "PATH=${PATH_STRING}\;${Boost_LIBRARY_DIRS}") +endif() + +foreach(TEST_NAME ${TEST_NAMES}) + add_executable(${TEST_NAME} ${TEST_NAME}.cpp) + target_link_libraries(${TEST_NAME} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} toml11::toml11) + target_include_directories(${TEST_NAME} SYSTEM PRIVATE ${Boost_INCLUDE_DIRS}) + target_compile_definitions(${TEST_NAME} PRIVATE "BOOST_TEST_MODULE=\"${TEST_NAME}\"") + + # to compile tests with ... + if(TOML11_REQUIRE_FILESYSTEM_LIBRARY) + if(TOML11_WITH_LIBCXX_LIBRARY) + target_link_libraries(${TEST_NAME} "c++fs") + else() + target_link_libraries(${TEST_NAME} "stdc++fs") + endif() + endif() + + target_include_directories(${TEST_NAME} PRIVATE ${Boost_INCLUDE_DIRS}) + + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if(toml11_TEST_WITH_ASAN) + set_target_properties(${TEST_NAME} PROPERTIES + COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer" + LINK_FLAGS "-fsanitize=address -fno-omit-frame-pointer") + elseif(toml11_TEST_WITH_UBSAN) + set_target_properties(${TEST_NAME} PROPERTIES + COMPILE_FLAGS "-fsanitize=undefined" + LINK_FLAGS "-fsanitize=undefined") + endif() + endif() + + add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + set_tests_properties(${TEST_NAME} PROPERTIES ENVIRONMENT "${TEST_ENVIRON}") +endforeach(TEST_NAME) + + +# this test is to check it compiles. it will not run +add_executable(test_multiple_translation_unit + test_multiple_translation_unit_1.cpp + test_multiple_translation_unit_2.cpp) +target_link_libraries(test_multiple_translation_unit toml11::toml11) + +if(WIN32) + add_executable(test_windows test_windows.cpp) + target_link_libraries(test_windows toml11::toml11) +endif() + diff --git a/external/toml11/tests/check.cpp b/external/toml11/tests/check.cpp new file mode 100644 index 0000000..bf67775 --- /dev/null +++ b/external/toml11/tests/check.cpp @@ -0,0 +1,42 @@ +#include + +#include +#include + +int main(int argc, char **argv) +{ + if(argc != 3) + { + std::cerr << "usage: ./check [filename] [valid|invalid]" << std::endl; + return 1; + } + + const std::string file_kind(argv[2]); + + try + { + const auto data = toml::parse(argv[1]); + std::cout << std::setprecision(16) << std::setw(80) << data; + if(file_kind == "valid") + { + return 0; + } + else + { + return 1; + } + } + catch(const toml::syntax_error& err) + { + std::cout << "what(): " << err.what() << std::endl; + if(file_kind == "invalid") + { + return 0; + } + else + { + return 1; + } + } + return 127; +} diff --git a/external/toml11/tests/check_serialization.cpp b/external/toml11/tests/check_serialization.cpp new file mode 100644 index 0000000..e97d51b --- /dev/null +++ b/external/toml11/tests/check_serialization.cpp @@ -0,0 +1,114 @@ +#include + +#include +#include + +int main(int argc, char **argv) +{ + if(argc != 2) + { + std::cerr << "usage: ./check [filename]" << std::endl; + return 1; + } + + const std::string filename(argv[1]); + + { + const auto data = toml::parse(filename); + { + std::ofstream ofs("tmp.toml"); + ofs << std::setprecision(16) << std::setw(80) << data; + } + const auto serialized = toml::parse("tmp.toml"); + + if(data != serialized) + { + // this is really a ditry hack, but is the easiest way... + // TODO: cleanup by adding comparison function to check if a value is NaN or not + if(filename.substr(filename.size() - 22, 22) == "float-inf-and-nan.toml" && + std::isnan (toml::find(serialized, "nan")) && + !std::signbit (toml::find(serialized, "nan")) && + std::isnan (toml::find(serialized, "nan_plus")) && + !std::signbit (toml::find(serialized, "nan_plus")) && + std::isnan (toml::find(serialized, "nan_neg")) && + std::signbit (toml::find(serialized, "nan_neg")) && + !std::isnan (toml::find(serialized, "infinity")) && + !std::isfinite(toml::find(serialized, "infinity")) && + !std::signbit (toml::find(serialized, "infinity")) && + !std::isnan (toml::find(serialized, "infinity_plus")) && + !std::isfinite(toml::find(serialized, "infinity_plus")) && + !std::signbit (toml::find(serialized, "infinity_plus")) && + !std::isnan (toml::find(serialized, "infinity_neg")) && + !std::isfinite(toml::find(serialized, "infinity_neg")) && + std::signbit (toml::find(serialized, "infinity_neg"))) + { + // then it is correctly serialized. + // Note that, the result of (nan == nan) is false. so `data == serialized` is false. + } + else + { + std::cerr << "============================================================\n"; + std::cerr << "result (w/o comment) different: " << filename << std::endl; + std::cerr << "------------------------------------------------------------\n"; + std::cerr << "# serialized\n"; + std::cerr << serialized; + std::cerr << "------------------------------------------------------------\n"; + std::cerr << "# data\n"; + std::cerr << data; + return 1; + } + } + } + { + const auto data = toml::parse(filename); + { + std::ofstream ofs("tmp.toml"); + ofs << std::setprecision(16) << std::setw(80) << data; + } + const auto serialized = toml::parse("tmp.toml"); + if(data != serialized) + { + // this is really a ditry hack, but is the easiest way... + // TODO: cleanup by adding comparison function to check if a value is NaN or not + if(filename.substr(filename.size() - 22, 22) == "float-inf-and-nan.toml" && + std::isnan (toml::find(serialized, "nan")) && + !std::signbit (toml::find(serialized, "nan")) && + std::isnan (toml::find(serialized, "nan_plus")) && + !std::signbit (toml::find(serialized, "nan_plus")) && + std::isnan (toml::find(serialized, "nan_neg")) && + std::signbit (toml::find(serialized, "nan_neg")) && + !std::isnan (toml::find(serialized, "infinity")) && + !std::isfinite(toml::find(serialized, "infinity")) && + !std::signbit (toml::find(serialized, "infinity")) && + !std::isnan (toml::find(serialized, "infinity_plus")) && + !std::isfinite(toml::find(serialized, "infinity_plus")) && + !std::signbit (toml::find(serialized, "infinity_plus")) && + !std::isnan (toml::find(serialized, "infinity_neg")) && + !std::isfinite(toml::find(serialized, "infinity_neg")) && + std::signbit (toml::find(serialized, "infinity_neg")) && + toml::find(data, "nan").comments() == toml::find(serialized, "nan").comments() && + toml::find(data, "nan_plus").comments() == toml::find(serialized, "nan_plus").comments() && + toml::find(data, "nan_neg").comments() == toml::find(serialized, "nan_neg").comments() && + toml::find(data, "infinity").comments() == toml::find(serialized, "infinity").comments() && + toml::find(data, "infinity_plus").comments() == toml::find(serialized, "infinity_plus").comments() && + toml::find(data, "infinity_neg").comments() == toml::find(serialized, "infinity_neg").comments() ) + { + // then it is correctly serialized. + // Note that, the result of (nan == nan) is false. so `data == serialized` is false. + } + else + { + std::cerr << "============================================================\n"; + std::cerr << "result (w/ comment) different: " << filename << std::endl; + std::cerr << "------------------------------------------------------------\n"; + std::cerr << "# serialized\n"; + std::cerr << serialized; + std::cerr << "------------------------------------------------------------\n"; + std::cerr << "# data\n"; + std::cerr << data; + return 1; + } + } + } + return 0; +} diff --git a/external/toml11/tests/check_toml_test.cpp b/external/toml11/tests/check_toml_test.cpp new file mode 100644 index 0000000..51404c9 --- /dev/null +++ b/external/toml11/tests/check_toml_test.cpp @@ -0,0 +1,139 @@ +#include + +#include +#include + +struct json_serializer +{ + void operator()(toml::boolean v) + { + std::cout << "{\"type\":\"bool\",\"value\":\"" << toml::value(v) << "\"}"; + return ; + } + void operator()(toml::integer v) + { + std::cout << "{\"type\":\"integer\",\"value\":\"" << toml::value(v) << "\"}"; + return ; + } + void operator()(toml::floating v) + { + if(std::isnan(v) && std::signbit(v)) + { + // toml-test does not allow negative NaN represented in "-nan" because + // there are languages that does not distinguish nan and -nan. + // But toml11 keeps sign from input. To resolve this difference, + // we convert -nan to nan here. + v = std::numeric_limits::quiet_NaN(); + } + std::cout << "{\"type\":\"float\",\"value\":\"" << toml::value(v) << "\"}"; + return ; + } + void operator()(const toml::string& v) + { + // since toml11 automatically convert string to multiline string that is + // valid only in TOML, we need to format the string to make it valid in + // JSON. + toml::serializer ser(std::numeric_limits::max()); + std::cout << "{\"type\":\"string\",\"value\":" + << ser(v.str) << "}"; + return ; + } + void operator()(const toml::local_time& v) + { + std::cout << "{\"type\":\"time-local\",\"value\":\"" << toml::value(v) << "\"}"; + return ; + } + void operator()(const toml::local_date& v) + { + std::cout << "{\"type\":\"date-local\",\"value\":\"" << toml::value(v) << "\"}"; + return ; + } + void operator()(const toml::local_datetime& v) + { + std::cout << "{\"type\":\"datetime-local\",\"value\":\"" << toml::value(v) << "\"}"; + return ; + } + void operator()(const toml::offset_datetime& v) + { + std::cout << "{\"type\":\"datetime\",\"value\":\"" << toml::value(v) << "\"}"; + return ; + } + void operator()(const toml::array& v) + { + if(!v.empty() && v.front().is_table()) + { + std::cout << '['; + bool is_first = true; + for(const auto& elem : v) + { + if(!is_first) {std::cout << ", ";} + is_first = false; + toml::visit(*this, elem); + } + std::cout << ']'; + } + else + { +// std::cout << "{\"type\":\"array\",\"value\":["; + std::cout << "["; + bool is_first = true; + for(const auto& elem : v) + { + if(!is_first) {std::cout << ", ";} + is_first = false; + toml::visit(*this, elem); + } + std::cout << "]"; + } + return ; + } + void operator()(const toml::table& v) + { + std::cout << '{'; + bool is_first = true; + for(const auto& elem : v) + { + if(!is_first) {std::cout << ", ";} + is_first = false; + const auto k = toml::format_key(elem.first); + if(k.at(0) == '"') + { + std::cout << k << ":"; + } + else // bare key + { + std::cout << '\"' << k << "\":"; + } + toml::visit(*this, elem.second); + } + std::cout << '}'; + return ; + } +}; + +int main() +{ + try + { + std::vector buf; + std::cin.peek(); + while(!std::cin.eof()) + { + buf.push_back(std::cin.get()); + std::cin.peek(); + } + std::string bufstr(buf.begin(), buf.end()); + + std::istringstream ss(bufstr); + + const auto data = toml::parse(ss); + std::cout << std::setprecision(std::numeric_limits::max_digits10); + toml::visit(json_serializer(), data); + return 0; + } + catch(const toml::syntax_error& err) + { + std::cout << "what(): " << err.what() << std::endl; + return 1; + } +} diff --git a/external/toml11/tests/test_comments.cpp b/external/toml11/tests/test_comments.cpp new file mode 100644 index 0000000..2d2b6a6 --- /dev/null +++ b/external/toml11/tests/test_comments.cpp @@ -0,0 +1,545 @@ +#include + +#include "unit_test.hpp" + +BOOST_AUTO_TEST_CASE(test_comment_before) +{ + { + const std::string file = R"( + # comment for a. + a = 42 + # comment for b. + b = "baz" + )"; + std::istringstream iss(file); + const auto v = toml::parse(iss); + + const auto& a = toml::find(v, "a"); + const auto& b = toml::find(v, "b"); + + BOOST_TEST(a.comments().size() == 1u); + BOOST_TEST(a.comments().front() == " comment for a."); + BOOST_TEST(b.comments().size() == 1u); + BOOST_TEST(b.comments().front() == " comment for b."); + } + { + const std::string file = R"( + # comment for a. + # another comment for a. + a = 42 + # comment for b. + # also comment for b. + b = "baz" + )"; + + std::istringstream iss(file); + const auto v = toml::parse(iss); + + const auto& a = toml::find(v, "a"); + const auto& b = toml::find(v, "b"); + + BOOST_TEST(a.comments().size() == 2u); + BOOST_TEST(a.comments().front() == " comment for a."); + BOOST_TEST(a.comments().back() == " another comment for a."); + BOOST_TEST(b.comments().size() == 2u); + BOOST_TEST(b.comments().front() == " comment for b."); + BOOST_TEST(b.comments().back() == " also comment for b."); + } +} + +BOOST_AUTO_TEST_CASE(test_comment_inline) +{ + { + const std::string file = R"( + a = 42 # comment for a. + b = "baz" # comment for b. + )"; + + std::istringstream iss(file); + const auto v = toml::parse(iss); + + const auto& a = toml::find(v, "a"); + const auto& b = toml::find(v, "b"); + + BOOST_TEST(a.comments().size() == 1u); + BOOST_TEST(a.comments().front() == " comment for a."); + BOOST_TEST(b.comments().size() == 1u); + BOOST_TEST(b.comments().front() == " comment for b."); + } + { + const std::string file = R"( + a = [ + 42, + ] # comment for a. + b = [ + "bar", # this is not a comment for b, but "bar" + ] # this is a comment for b. + )"; + + std::istringstream iss(file); + const auto v = toml::parse(iss); + + const auto& a = toml::find(v, "a"); + const auto& b = toml::find(v, "b"); + const auto& b0 = b.as_array().at(0); + + BOOST_TEST(a.comments().size() == 1u); + BOOST_TEST(a.comments().front() == " comment for a."); + BOOST_TEST(b.comments().size() == 1u); + BOOST_TEST(b.comments().front() == " this is a comment for b."); + BOOST_TEST(b0.comments().size() == 1u); + BOOST_TEST(b0.comments().front() == " this is not a comment for b, but \"bar\""); + } +} + +BOOST_AUTO_TEST_CASE(test_comment_both) +{ + { + const std::string file = R"( + # comment for a. + a = 42 # inline comment for a. + # comment for b. + b = "baz" # inline comment for b. + # comment for c. + c = [ # this comment will be ignored + # comment for the first element. + 10 # this also. + ] # another comment for c. + )"; + + std::istringstream iss(file); + const auto v = toml::parse(iss); + + const auto& a = toml::find(v, "a"); + const auto& b = toml::find(v, "b"); + const auto& c = toml::find(v, "c"); + const auto& c0 = c.as_array().at(0); + + BOOST_TEST(a.comments().size() == 2u); + BOOST_TEST(a.comments().front() == " comment for a."); + BOOST_TEST(a.comments().back() == " inline comment for a."); + BOOST_TEST(b.comments().size() == 2u); + BOOST_TEST(b.comments().front() == " comment for b."); + BOOST_TEST(b.comments().back() == " inline comment for b."); + + BOOST_TEST(c.comments().size() == 2u); + BOOST_TEST(c.comments().front() == " comment for c."); + BOOST_TEST(c.comments().back() == " another comment for c."); + + BOOST_TEST(c0.comments().size() == 2u); + BOOST_TEST(c0.comments().front() == " comment for the first element."); + BOOST_TEST(c0.comments().back() == " this also."); + } +} + +BOOST_AUTO_TEST_CASE(test_comments_on_implicit_values) +{ + { + const std::string file = R"( + # comment for the first element of array-of-tables. + [[array-of-tables]] + foo = "bar" + )"; + std::istringstream iss(file); + const auto v = toml::parse(iss); + + const auto aot = toml::find(v, "array-of-tables"); + const auto elm = aot.at(0); + BOOST_TEST(aot.comments().empty()); + BOOST_TEST(elm.comments().size() == 1); + BOOST_TEST(elm.comments().front() == " comment for the first element of array-of-tables."); + } + { + const std::string file = R"( + # comment for the array itself + array-of-tables = [ + # comment for the first element of array-of-tables. + {foo = "bar"} + ] + )"; + std::istringstream iss(file); + const auto v = toml::parse(iss); + + const auto aot = toml::find(v, "array-of-tables"); + const auto elm = aot.at(0); + BOOST_TEST(aot.comments().size() == 1); + BOOST_TEST(aot.comments().front() == " comment for the array itself"); + BOOST_TEST(elm.comments().size() == 1); + BOOST_TEST(elm.comments().front() == " comment for the first element of array-of-tables."); + } +} + +BOOST_AUTO_TEST_CASE(test_discard_comment) +{ + const std::string file = R"( + # comment for a. + a = 42 # inline comment for a. + # comment for b. + b = "baz" # inline comment for b. + # comment for c. + c = [ # this comment will be ignored + # comment for the first element. + 10 # this also. + ] # another comment for c. + )"; + + std::istringstream iss(file); + const auto v = toml::parse(iss); + + const auto& a = toml::find(v, "a"); + const auto& b = toml::find(v, "b"); + const auto& c = toml::find(v, "c"); + const auto& c0 = c.as_array().at(0); + + BOOST_TEST(a.comments().empty()); + BOOST_TEST(b.comments().empty()); + BOOST_TEST(c.comments().empty()); + BOOST_TEST(c0.comments().empty()); +} + +BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) +{ + using value_type = toml::basic_value; + { + const value_type v(true, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_boolean()); + BOOST_TEST(v.as_boolean() == true); + } + { + const value_type v(42, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_integer()); + BOOST_TEST(v.as_integer() == 42); + } + { + const value_type v(3.14, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_floating()); + BOOST_TEST(v.as_floating() == 3.14); + } + { + const value_type v(toml::string("str"), {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_string()); + BOOST_TEST(v.as_string() == "str"); + } + { + const value_type v(std::string("str"), {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_string()); + BOOST_TEST(v.as_string() == "str"); + } + { + const value_type v(std::string("str"), toml::string_t::literal, + {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_string()); + BOOST_TEST(v.as_string() == "str"); + } + { + const value_type v("str", {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_string()); + BOOST_TEST(v.as_string() == "str"); + } + { + const value_type v("str", toml::string_t::literal, + {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_string()); + BOOST_TEST(v.as_string() == "str"); + } +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L + { + using namespace std::literals::string_view_literals; + const value_type v("str"sv, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_string()); + BOOST_TEST(v.as_string() == "str"); + } + { + using namespace std::literals::string_view_literals; + const value_type v("str"sv, toml::string_t::literal, + {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_string()); + BOOST_TEST(v.as_string() == "str"); + } +#endif + const toml::local_date ld{2019, toml::month_t::Apr, 1}; + const toml::local_time lt{12, 30, 45}; + const toml::local_datetime ldt{ld, lt}; + const toml::offset_datetime odt{ld, lt, toml::time_offset{9, 0}}; + { + const value_type v(ld, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_local_date()); + BOOST_TEST(v.as_local_date() == ld); + } + { + const value_type v(lt, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_local_time()); + BOOST_TEST(v.as_local_time() == lt); + } + { + const toml::local_time three_hours{3,0,0}; + const value_type v(std::chrono::hours(3), {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_local_time()); + BOOST_TEST(v.as_local_time() == three_hours); + } + { + const value_type v(ldt, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_local_datetime()); + BOOST_TEST(v.as_local_datetime() == ldt); + } + { + const value_type v(odt, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_offset_datetime()); + BOOST_TEST(v.as_offset_datetime() == odt); + } + { + const auto systp = static_cast(odt); + const value_type v(systp, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_offset_datetime()); + + // While the conversion, the information about time offset may change. + const auto systp2 = static_cast( + v.as_offset_datetime()); + const bool result = systp == systp2; // because there is no operator<< + BOOST_TEST(result); + } + { + const typename value_type::array_type a{1,2,3,4,5}; + const value_type v(a, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_array()); + BOOST_TEST(v.as_array().at(0).is_integer()); + BOOST_TEST(v.as_array().at(1).is_integer()); + BOOST_TEST(v.as_array().at(2).is_integer()); + BOOST_TEST(v.as_array().at(3).is_integer()); + BOOST_TEST(v.as_array().at(4).is_integer()); + BOOST_TEST(v.as_array().at(0).as_integer() == 1); + BOOST_TEST(v.as_array().at(1).as_integer() == 2); + BOOST_TEST(v.as_array().at(2).as_integer() == 3); + BOOST_TEST(v.as_array().at(3).as_integer() == 4); + BOOST_TEST(v.as_array().at(4).as_integer() == 5); + } + { + const std::initializer_list a = {1,2,3,4,5}; + const value_type v(a, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_array()); + BOOST_TEST(v.as_array().at(0).is_integer()); + BOOST_TEST(v.as_array().at(1).is_integer()); + BOOST_TEST(v.as_array().at(2).is_integer()); + BOOST_TEST(v.as_array().at(3).is_integer()); + BOOST_TEST(v.as_array().at(4).is_integer()); + BOOST_TEST(v.as_array().at(0).as_integer() == 1); + BOOST_TEST(v.as_array().at(1).as_integer() == 2); + BOOST_TEST(v.as_array().at(2).as_integer() == 3); + BOOST_TEST(v.as_array().at(3).as_integer() == 4); + BOOST_TEST(v.as_array().at(4).as_integer() == 5); + } + { + const std::vector a = {1,2,3,4,5}; + const value_type v(a, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_array()); + BOOST_TEST(v.as_array().at(0).is_integer()); + BOOST_TEST(v.as_array().at(1).is_integer()); + BOOST_TEST(v.as_array().at(2).is_integer()); + BOOST_TEST(v.as_array().at(3).is_integer()); + BOOST_TEST(v.as_array().at(4).is_integer()); + BOOST_TEST(v.as_array().at(0).as_integer() == 1); + BOOST_TEST(v.as_array().at(1).as_integer() == 2); + BOOST_TEST(v.as_array().at(2).as_integer() == 3); + BOOST_TEST(v.as_array().at(3).as_integer() == 4); + BOOST_TEST(v.as_array().at(4).as_integer() == 5); + } + { + const typename value_type::table_type t{ + {"key1", 42}, {"key2", "foobar"} + }; + const value_type v(t, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_table()); + BOOST_TEST(v.as_table().at("key1").is_integer()); + BOOST_TEST(v.as_table().at("key1").as_integer() == 42); + BOOST_TEST(v.as_table().at("key2").is_string()); + BOOST_TEST(v.as_table().at("key2").as_string() == "foobar"); + } + { + const std::initializer_list> t{ + {"key1", 42}, {"key2", "foobar"} + }; + const value_type v(t, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_table()); + BOOST_TEST(v.as_table().at("key1").is_integer()); + BOOST_TEST(v.as_table().at("key1").as_integer() == 42); + BOOST_TEST(v.as_table().at("key2").is_string()); + BOOST_TEST(v.as_table().at("key2").as_string() == "foobar"); + } + { + const std::map t{ + {"key1", 42}, {"key2", "foobar"} + }; + const value_type v(t, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_table()); + BOOST_TEST(v.as_table().at("key1").is_integer()); + BOOST_TEST(v.as_table().at("key1").as_integer() == 42); + BOOST_TEST(v.as_table().at("key2").is_string()); + BOOST_TEST(v.as_table().at("key2").as_string() == "foobar"); + } +} + +BOOST_AUTO_TEST_CASE(test_overwrite_comments) +{ + using value_type = toml::basic_value; + { + const value_type v(42, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_integer()); + BOOST_TEST(v.as_integer() == 42); + + const value_type u(v, {"comment3", "comment4"}); + BOOST_TEST(u.comments().size() == 2u); + BOOST_TEST(u.comments().at(0) == "comment3"); + BOOST_TEST(u.comments().at(1) == "comment4"); + BOOST_TEST(u.is_integer()); + BOOST_TEST(u.as_integer() == 42); + } + { + const value_type v(42, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_integer()); + BOOST_TEST(v.as_integer() == 42); + + const value_type u(v); + BOOST_TEST(u.comments().size() == 2u); + BOOST_TEST(u.comments().at(0) == "comment1"); + BOOST_TEST(u.comments().at(1) == "comment2"); + BOOST_TEST(u.is_integer()); + BOOST_TEST(u.as_integer() == 42); + } + { + const value_type v(42, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2u); + BOOST_TEST(v.comments().at(0) == "comment1"); + BOOST_TEST(v.comments().at(1) == "comment2"); + BOOST_TEST(v.is_integer()); + BOOST_TEST(v.as_integer() == 42); + + const value_type u(v, {}); + BOOST_TEST(u.comments().size() == 0u); + BOOST_TEST(u.is_integer()); + BOOST_TEST(u.as_integer() == 42); + } +} + +BOOST_AUTO_TEST_CASE(test_output_comments) +{ + using value_type = toml::basic_value; + { + const value_type v(42, {"comment1", "comment2"}); + std::ostringstream oss; + oss << v.comments(); + + std::ostringstream ref; + ref << "#comment1\n"; + ref << "#comment2\n"; + + BOOST_TEST(oss.str() == ref.str()); + } + { + const value_type v(42, {"comment1", "comment2"}); + std::ostringstream oss; + + // If v is not a table, toml11 assumes that user is writing something + // like the following. + + oss << "answer = " << v; + + BOOST_TEST(oss.str() == "answer = 42 #comment1comment2"); + } + + { + const value_type v(42, {"comment1", "comment2"}); + std::ostringstream oss; + + // If v is not a table, toml11 assumes that user is writing something + // like the following. + + oss << toml::nocomment << "answer = " << v; + + BOOST_TEST(oss.str() == "answer = 42"); + } + + { + const value_type v(42, {"comment1", "comment2"}); + std::ostringstream oss; + + // If v is not a table, toml11 assumes that user is writing something + // like the following. + + oss << toml::nocomment << toml::showcomment << "answer = " << v; + + BOOST_TEST(oss.str() == "answer = 42 #comment1comment2"); + } + +} diff --git a/external/toml11/tests/test_datetime.cpp b/external/toml11/tests/test_datetime.cpp new file mode 100644 index 0000000..bbbcc42 --- /dev/null +++ b/external/toml11/tests/test_datetime.cpp @@ -0,0 +1,117 @@ +#include + +#include "unit_test.hpp" + +BOOST_AUTO_TEST_CASE(test_local_date) +{ + const toml::local_date date(2018, toml::month_t::Jan, 1); + const toml::local_date date1(date); + BOOST_TEST(date == date1); + + const std::chrono::system_clock::time_point tp(date); + const toml::local_date date2(tp); + BOOST_TEST(date == date2); + + const toml::local_date date3(2017, toml::month_t::Dec, 31); + BOOST_TEST(date > date3); + + std::ostringstream oss; + oss << date; + BOOST_TEST(oss.str() == std::string("2018-01-01")); +} + +BOOST_AUTO_TEST_CASE(test_local_time) +{ + const toml::local_time time(12, 30, 45); + const toml::local_time time1(time); + BOOST_TEST(time == time1); + + const std::chrono::nanoseconds dur(time); + std::chrono::nanoseconds ns(0); + ns += std::chrono::hours (12); + ns += std::chrono::minutes(30); + ns += std::chrono::seconds(45); + BOOST_TEST(dur.count() == ns.count()); + + const toml::local_time time3(12, 15, 45); + BOOST_TEST(time > time3); + + { + std::ostringstream oss; + oss << time; + BOOST_TEST(oss.str() == std::string("12:30:45")); + } + + { + const toml::local_time time4(12, 30, 45, 123, 456); + std::ostringstream oss; + oss << time4; + BOOST_TEST(oss.str() == std::string("12:30:45.123456")); + } +} + +BOOST_AUTO_TEST_CASE(test_time_offset) +{ + const toml::time_offset time(9, 30); + const toml::time_offset time1(time); + BOOST_TEST(time == time1); + + const std::chrono::minutes dur(time); + std::chrono::minutes m(0); + m += std::chrono::hours (9); + m += std::chrono::minutes(30); + BOOST_TEST(dur.count() == m.count()); + + const toml::time_offset time2(9, 0); + BOOST_TEST(time2 < time); + + std::ostringstream oss; + oss << time; + BOOST_TEST(oss.str() == std::string("+09:30")); +} + +BOOST_AUTO_TEST_CASE(test_local_datetime) +{ + const toml::local_datetime dt(toml::local_date(2018, toml::month_t::Jan, 1), + toml::local_time(12, 30, 45)); + const toml::local_datetime dt1(dt); + BOOST_TEST(dt == dt1); + + const std::chrono::system_clock::time_point tp(dt); + const toml::local_datetime dt2(tp); + BOOST_TEST(dt == dt2); + + std::ostringstream oss; + oss << dt; + BOOST_TEST(oss.str() == std::string("2018-01-01T12:30:45")); +} + +BOOST_AUTO_TEST_CASE(test_offset_datetime) +{ + const toml::offset_datetime dt(toml::local_date(2018, toml::month_t::Jan, 1), + toml::local_time(12, 30, 45), + toml::time_offset(9, 30)); + const toml::offset_datetime dt1(dt); + BOOST_TEST(dt == dt1); + + const std::chrono::system_clock::time_point tp1(dt); + const toml::offset_datetime dt2(tp1); + const std::chrono::system_clock::time_point tp2(dt2); + const bool tp_same = (tp1 == tp2); + BOOST_TEST(tp_same); + + { + std::ostringstream oss; + oss << dt; + BOOST_TEST(oss.str() == std::string("2018-01-01T12:30:45+09:30")); + } + { + const toml::offset_datetime dt3( + toml::local_date(2018, toml::month_t::Jan, 1), + toml::local_time(12, 30, 45), + toml::time_offset(0, 0)); + std::ostringstream oss; + oss << dt3; + BOOST_TEST(oss.str() == std::string("2018-01-01T12:30:45Z")); + } +} diff --git a/external/toml11/tests/test_error_detection.cpp b/external/toml11/tests/test_error_detection.cpp new file mode 100644 index 0000000..5e39ef6 --- /dev/null +++ b/external/toml11/tests/test_error_detection.cpp @@ -0,0 +1,97 @@ +#include + +#include "unit_test.hpp" + +#include +#include + +BOOST_AUTO_TEST_CASE(test_detect_empty_key) +{ + std::istringstream stream(std::string("= \"value\"")); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); +} + +BOOST_AUTO_TEST_CASE(test_detect_missing_value) +{ + std::istringstream stream(std::string("a =")); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); +} + +BOOST_AUTO_TEST_CASE(test_detect_too_many_value) +{ + std::istringstream stream(std::string("a = 1 = \"value\"")); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); +} + +BOOST_AUTO_TEST_CASE(test_detect_duplicate_table) +{ + std::istringstream stream(std::string( + "[table]\n" + "a = 42\n" + "[table]\n" + "b = 42\n" + )); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); +} + +BOOST_AUTO_TEST_CASE(test_detect_conflict_array_table) +{ + std::istringstream stream(std::string( + "[[table]]\n" + "a = 42\n" + "[table]\n" + "b = 42\n" + )); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); +} + +BOOST_AUTO_TEST_CASE(test_detect_conflict_table_array) +{ + std::istringstream stream(std::string( + "[table]\n" + "a = 42\n" + "[[table]]\n" + "b = 42\n" + )); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); +} + +BOOST_AUTO_TEST_CASE(test_detect_duplicate_value) +{ + std::istringstream stream(std::string( + "a = 1\n" + "a = 2\n" + )); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); +} + +BOOST_AUTO_TEST_CASE(test_detect_conflicting_value) +{ + std::istringstream stream(std::string( + "a.b = 1\n" + "a.b.c = 2\n" + )); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); +} + +BOOST_AUTO_TEST_CASE(test_detect_inhomogeneous_array) +{ +#ifdef TOML11_DISALLOW_HETEROGENEOUS_ARRAYS + std::istringstream stream(std::string( + "a = [1, 1.0]\n" + )); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); +#else + BOOST_TEST_MESSAGE("After v1.0.0-rc.1, heterogeneous arrays are allowed"); +#endif +} + +BOOST_AUTO_TEST_CASE(test_detect_appending_array_of_table) +{ + std::istringstream stream(std::string( + "a = [{b = 1}]\n" + "[[a]]\n" + "b = 2\n" + )); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); +} diff --git a/external/toml11/tests/test_expect.cpp b/external/toml11/tests/test_expect.cpp new file mode 100644 index 0000000..308d4fb --- /dev/null +++ b/external/toml11/tests/test_expect.cpp @@ -0,0 +1,26 @@ +#include + +#include "unit_test.hpp" + +#include +#include +#include +#include +#include + +BOOST_AUTO_TEST_CASE(test_expect) +{ + { + toml::value v1(42); + toml::value v2(3.14); + const auto v1_or_0 = toml::expect(v1).unwrap_or(0); + const auto v2_or_0 = toml::expect(v2).unwrap_or(0); + BOOST_TEST(42 == v1_or_0); + BOOST_TEST( 0 == v2_or_0); + + const auto v1_or_none = toml::expect(v1).map([](int i){return std::to_string(i);}).unwrap_or(std::string("none")); + const auto v2_or_none = toml::expect(v2).map([](int i){return std::to_string(i);}).unwrap_or(std::string("none")); + BOOST_TEST("42" == v1_or_none); + BOOST_TEST("none" == v2_or_none); + } +} diff --git a/external/toml11/tests/test_extended_conversions.cpp b/external/toml11/tests/test_extended_conversions.cpp new file mode 100644 index 0000000..1b21264 --- /dev/null +++ b/external/toml11/tests/test_extended_conversions.cpp @@ -0,0 +1,627 @@ +#include + +#include "unit_test.hpp" + +#include +#include + +namespace extlib +{ +struct foo +{ + int a; + std::string b; +}; +struct bar +{ + int a; + std::string b; + + void from_toml(const toml::value& v) + { + this->a = toml::find(v, "a"); + this->b = toml::find(v, "b"); + return ; + } + + toml::table into_toml() const + { + return toml::table{{"a", this->a}, {"b", this->b}}; + } +}; + +struct baz +{ + int a; + std::string b; +}; +struct qux +{ + int a; + std::string b; +}; + +struct foobar +{ + // via constructor + explicit foobar(const toml::value& v) + : a(toml::find(v, "a")), b(toml::find(v, "b")) + {} + int a; + std::string b; +}; +} // extlib + +namespace toml +{ +template<> +struct from +{ + static extlib::foo from_toml(const toml::value& v) + { + return extlib::foo{toml::find(v, "a"), toml::find(v, "b")}; + } +}; + +template<> +struct into +{ + static toml::value into_toml(const extlib::foo& f) + { + return toml::value{{"a", f.a}, {"b", f.b}}; + } +}; + +template<> +struct from +{ + static extlib::baz from_toml(const toml::value& v) + { + return extlib::baz{toml::find(v, "a"), toml::find(v, "b")}; + } +}; + +template<> +struct into +{ + static toml::table into_toml(const extlib::qux& f) + { + return toml::table{{"a", f.a}, {"b", f.b}}; + } +}; +} // toml + +// --------------------------------------------------------------------------- + +namespace extlib2 +{ +struct foo +{ + int a; + std::string b; +}; +struct bar +{ + int a; + std::string b; + + template class M, template class A> + void from_toml(const toml::basic_value& v) + { + this->a = toml::find(v, "a"); + this->b = toml::find(v, "b"); + return ; + } + + toml::table into_toml() const + { + return toml::table{{"a", this->a}, {"b", this->b}}; + } +}; +struct baz +{ + int a; + std::string b; +}; +struct qux +{ + int a; + std::string b; +}; + +struct foobar +{ + template class M, template class A> + explicit foobar(const toml::basic_value& v) + : a(toml::find(v, "a")), b(toml::find(v, "b")) + {} + int a; + std::string b; +}; + +} // extlib2 + +namespace toml +{ +template<> +struct from +{ + template class M, template class A> + static extlib2::foo from_toml(const toml::basic_value& v) + { + return extlib2::foo{toml::find(v, "a"), toml::find(v, "b")}; + } +}; + +template<> +struct into +{ + static toml::table into_toml(const extlib2::foo& f) + { + return toml::table{{"a", f.a}, {"b", f.b}}; + } +}; + +template<> +struct from +{ + template class M, template class A> + static extlib2::baz from_toml(const toml::basic_value& v) + { + return extlib2::baz{toml::find(v, "a"), toml::find(v, "b")}; + } +}; + +template<> +struct into +{ + static toml::basic_value + into_toml(const extlib2::qux& f) + { + return toml::basic_value{ + {"a", f.a}, {"b", f.b} + }; + } +}; +} // toml + +// --------------------------------------------------------------------------- + +BOOST_AUTO_TEST_CASE(test_conversion_by_member_methods) +{ + { + const toml::value v{{"a", 42}, {"b", "baz"}}; + + const auto foo = toml::get(v); + BOOST_TEST(foo.a == 42); + BOOST_TEST(foo.b == "baz"); + + const toml::value v2(foo); + + BOOST_TEST(v == v2); + } + + { + const toml::value v{{"a", 42}, {"b", "baz"}}; + + const auto foo = toml::get(v); + BOOST_TEST(foo.a == 42); + BOOST_TEST(foo.b == "baz"); + + const toml::value v2(foo); + BOOST_TEST(v == v2); + } + + { + const toml::basic_value + v{{"a", 42}, {"b", "baz"}}; + + const auto foo = toml::get(v); + BOOST_TEST(foo.a == 42); + BOOST_TEST(foo.b == "baz"); + + const toml::basic_value + v2(foo); + + BOOST_TEST(v == v2); + } +} + +BOOST_AUTO_TEST_CASE(test_conversion_by_specialization) +{ + { + const toml::value v{{"a", 42}, {"b", "baz"}}; + + const auto bar = toml::get(v); + BOOST_TEST(bar.a == 42); + BOOST_TEST(bar.b == "baz"); + + const toml::value v2(bar); + + BOOST_TEST(v == v2); + } + { + const toml::value v{{"a", 42}, {"b", "baz"}}; + + const auto bar = toml::get(v); + BOOST_TEST(bar.a == 42); + BOOST_TEST(bar.b == "baz"); + + const toml::value v2(bar); + + BOOST_TEST(v == v2); + } + { + const toml::basic_value + v{{"a", 42}, {"b", "baz"}}; + + const auto bar = toml::get(v); + BOOST_TEST(bar.a == 42); + BOOST_TEST(bar.b == "baz"); + + const toml::basic_value + v2(bar); + + BOOST_TEST(v == v2); + } +} + +BOOST_AUTO_TEST_CASE(test_conversion_one_way) +{ + { + const toml::value v{{"a", 42}, {"b", "baz"}}; + + const auto baz = toml::get(v); + BOOST_TEST(baz.a == 42); + BOOST_TEST(baz.b == "baz"); + } + { + const extlib::qux q{42, "qux"}; + const toml::value v(q); + + BOOST_TEST(toml::find(v, "a") == 42); + BOOST_TEST(toml::find(v, "b") == "qux"); + } + + { + const toml::basic_value v{ + {"a", 42}, {"b", "baz"} + }; + + const auto baz = toml::get(v); + BOOST_TEST(baz.a == 42); + BOOST_TEST(baz.b == "baz"); + } + { + const extlib::qux q{42, "qux"}; + const toml::basic_value v(q); + + BOOST_TEST(toml::find(v, "a") == 42); + BOOST_TEST(toml::find(v, "b") == "qux"); + } +} + +BOOST_AUTO_TEST_CASE(test_conversion_via_constructor) +{ + { + const toml::value v{{"a", 42}, {"b", "foobar"}}; + + const auto foobar = toml::get(v); + BOOST_TEST(foobar.a == 42); + BOOST_TEST(foobar.b == "foobar"); + } + + { + const toml::basic_value v{ + {"a", 42}, {"b", "foobar"} + }; + + const auto foobar = toml::get(v); + BOOST_TEST(foobar.a == 42); + BOOST_TEST(foobar.b == "foobar"); + } +} + +BOOST_AUTO_TEST_CASE(test_recursive_conversion) +{ + { + const toml::value v{ + toml::table{{"a", 42}, {"b", "baz"}}, + toml::table{{"a", 43}, {"b", "qux"}}, + toml::table{{"a", 44}, {"b", "quux"}}, + toml::table{{"a", 45}, {"b", "foobar"}}, + }; + + const auto foos = toml::get>(v); + BOOST_TEST(foos.size() == 4ul); + BOOST_TEST(foos.at(0).a == 42); + BOOST_TEST(foos.at(1).a == 43); + BOOST_TEST(foos.at(2).a == 44); + BOOST_TEST(foos.at(3).a == 45); + + BOOST_TEST(foos.at(0).b == "baz"); + BOOST_TEST(foos.at(1).b == "qux"); + BOOST_TEST(foos.at(2).b == "quux"); + BOOST_TEST(foos.at(3).b == "foobar"); + + const auto bars = toml::get>(v); + BOOST_TEST(bars.size() == 4ul); + BOOST_TEST(bars.at(0).a == 42); + BOOST_TEST(bars.at(1).a == 43); + BOOST_TEST(bars.at(2).a == 44); + BOOST_TEST(bars.at(3).a == 45); + + BOOST_TEST(bars.at(0).b == "baz"); + BOOST_TEST(bars.at(1).b == "qux"); + BOOST_TEST(bars.at(2).b == "quux"); + BOOST_TEST(bars.at(3).b == "foobar"); + } + { + const toml::value v{ + toml::table{{"a", 42}, {"b", "baz"}}, + toml::table{{"a", 43}, {"b", "qux"}}, + toml::table{{"a", 44}, {"b", "quux"}}, + toml::table{{"a", 45}, {"b", "foobar"}}, + }; + + const auto foos = toml::get>(v); + BOOST_TEST(foos.size() == 4ul); + BOOST_TEST(foos.at(0).a == 42); + BOOST_TEST(foos.at(1).a == 43); + BOOST_TEST(foos.at(2).a == 44); + BOOST_TEST(foos.at(3).a == 45); + + BOOST_TEST(foos.at(0).b == "baz"); + BOOST_TEST(foos.at(1).b == "qux"); + BOOST_TEST(foos.at(2).b == "quux"); + BOOST_TEST(foos.at(3).b == "foobar"); + + const auto bars = toml::get>(v); + BOOST_TEST(bars.size() == 4ul); + BOOST_TEST(bars.at(0).a == 42); + BOOST_TEST(bars.at(1).a == 43); + BOOST_TEST(bars.at(2).a == 44); + BOOST_TEST(bars.at(3).a == 45); + + BOOST_TEST(bars.at(0).b == "baz"); + BOOST_TEST(bars.at(1).b == "qux"); + BOOST_TEST(bars.at(2).b == "quux"); + BOOST_TEST(bars.at(3).b == "foobar"); + } + + { + const toml::basic_value + v{ + toml::table{{"a", 42}, {"b", "baz"}}, + toml::table{{"a", 43}, {"b", "qux"}}, + toml::table{{"a", 44}, {"b", "quux"}}, + toml::table{{"a", 45}, {"b", "foobar"}} + }; + + const auto foos = toml::get>(v); + BOOST_TEST(foos.size() == 4ul); + BOOST_TEST(foos.at(0).a == 42); + BOOST_TEST(foos.at(1).a == 43); + BOOST_TEST(foos.at(2).a == 44); + BOOST_TEST(foos.at(3).a == 45); + + BOOST_TEST(foos.at(0).b == "baz"); + BOOST_TEST(foos.at(1).b == "qux"); + BOOST_TEST(foos.at(2).b == "quux"); + BOOST_TEST(foos.at(3).b == "foobar"); + + const auto bars = toml::get>(v); + BOOST_TEST(bars.size() == 4ul); + BOOST_TEST(bars.at(0).a == 42); + BOOST_TEST(bars.at(1).a == 43); + BOOST_TEST(bars.at(2).a == 44); + BOOST_TEST(bars.at(3).a == 45); + + BOOST_TEST(bars.at(0).b == "baz"); + BOOST_TEST(bars.at(1).b == "qux"); + BOOST_TEST(bars.at(2).b == "quux"); + BOOST_TEST(bars.at(3).b == "foobar"); + } + + // via constructor + { + const toml::value v{ + toml::table{{"a", 42}, {"b", "baz"}}, + toml::table{{"a", 43}, {"b", "qux"}}, + toml::table{{"a", 44}, {"b", "quux"}}, + toml::table{{"a", 45}, {"b", "foobar"}} + }; + + { + const auto foobars = toml::get>(v); + BOOST_TEST(foobars.size() == 4ul); + BOOST_TEST(foobars.at(0).a == 42); + BOOST_TEST(foobars.at(1).a == 43); + BOOST_TEST(foobars.at(2).a == 44); + BOOST_TEST(foobars.at(3).a == 45); + + BOOST_TEST(foobars.at(0).b == "baz"); + BOOST_TEST(foobars.at(1).b == "qux"); + BOOST_TEST(foobars.at(2).b == "quux"); + BOOST_TEST(foobars.at(3).b == "foobar"); + } + { + const auto foobars = toml::get>(v); + BOOST_TEST(foobars.size() == 4ul); + BOOST_TEST(foobars.at(0).a == 42); + BOOST_TEST(foobars.at(1).a == 43); + BOOST_TEST(foobars.at(2).a == 44); + BOOST_TEST(foobars.at(3).a == 45); + + BOOST_TEST(foobars.at(0).b == "baz"); + BOOST_TEST(foobars.at(1).b == "qux"); + BOOST_TEST(foobars.at(2).b == "quux"); + BOOST_TEST(foobars.at(3).b == "foobar"); + } + } + { + const toml::basic_value + v{ + toml::table{{"a", 42}, {"b", "baz"}}, + toml::table{{"a", 43}, {"b", "qux"}}, + toml::table{{"a", 44}, {"b", "quux"}}, + toml::table{{"a", 45}, {"b", "foobar"}} + }; + + const auto foobars = toml::get>(v); + BOOST_TEST(foobars.size() == 4ul); + BOOST_TEST(foobars.at(0).a == 42); + BOOST_TEST(foobars.at(1).a == 43); + BOOST_TEST(foobars.at(2).a == 44); + BOOST_TEST(foobars.at(3).a == 45); + + BOOST_TEST(foobars.at(0).b == "baz"); + BOOST_TEST(foobars.at(1).b == "qux"); + BOOST_TEST(foobars.at(2).b == "quux"); + BOOST_TEST(foobars.at(3).b == "foobar"); + } + + // via constructor + { + const toml::value v{ + {"0", toml::table{{"a", 42}, {"b", "baz"}}}, + {"1", toml::table{{"a", 43}, {"b", "qux"}}}, + {"2", toml::table{{"a", 44}, {"b", "quux"}}}, + {"3", toml::table{{"a", 45}, {"b", "foobar"}}} + }; + + { + const auto foobars = toml::get>(v); + BOOST_TEST(foobars.size() == 4ul); + BOOST_TEST(foobars.at("0").a == 42); + BOOST_TEST(foobars.at("1").a == 43); + BOOST_TEST(foobars.at("2").a == 44); + BOOST_TEST(foobars.at("3").a == 45); + + BOOST_TEST(foobars.at("0").b == "baz"); + BOOST_TEST(foobars.at("1").b == "qux"); + BOOST_TEST(foobars.at("2").b == "quux"); + BOOST_TEST(foobars.at("3").b == "foobar"); + } + { + const auto foobars = toml::get>(v); + BOOST_TEST(foobars.size() == 4ul); + BOOST_TEST(foobars.at("0").a == 42); + BOOST_TEST(foobars.at("1").a == 43); + BOOST_TEST(foobars.at("2").a == 44); + BOOST_TEST(foobars.at("3").a == 45); + + BOOST_TEST(foobars.at("0").b == "baz"); + BOOST_TEST(foobars.at("1").b == "qux"); + BOOST_TEST(foobars.at("2").b == "quux"); + BOOST_TEST(foobars.at("3").b == "foobar"); + } + } + { + const toml::basic_value + v{ + {"0", toml::table{{"a", 42}, {"b", "baz"}}}, + {"1", toml::table{{"a", 43}, {"b", "qux"}}}, + {"2", toml::table{{"a", 44}, {"b", "quux"}}}, + {"3", toml::table{{"a", 45}, {"b", "foobar"}}} + }; + + const auto foobars = toml::get>(v); + BOOST_TEST(foobars.size() == 4ul); + BOOST_TEST(foobars.at("0").a == 42); + BOOST_TEST(foobars.at("1").a == 43); + BOOST_TEST(foobars.at("2").a == 44); + BOOST_TEST(foobars.at("3").a == 45); + + BOOST_TEST(foobars.at("0").b == "baz"); + BOOST_TEST(foobars.at("1").b == "qux"); + BOOST_TEST(foobars.at("2").b == "quux"); + BOOST_TEST(foobars.at("3").b == "foobar"); + } + +} + +// =========================================================================== + +#ifndef TOML11_WITHOUT_DEFINE_NON_INTRUSIVE + +namespace extlib3 +{ +struct foo +{ + int a; + std::string b; +}; +struct bar +{ + int a; + std::string b; + foo f; +}; + +} // extlib3 + +TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(extlib3::foo, a, b) +TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(extlib3::bar, a, b, f) + +BOOST_AUTO_TEST_CASE(test_conversion_via_macro) +{ + { + const toml::value v{{"a", 42}, {"b", "baz"}}; + + const auto foo = toml::get(v); + BOOST_TEST(foo.a == 42); + BOOST_TEST(foo.b == "baz"); + + const toml::value v2(foo); + BOOST_TEST(v2 == v); + } + { + const toml::basic_value v{ + {"a", 42}, {"b", "baz"} + }; + + const auto foo = toml::get(v); + BOOST_TEST(foo.a == 42); + BOOST_TEST(foo.b == "baz"); + + const toml::basic_value v2(foo); + BOOST_TEST(v2 == v); + } + + // ----------------------------------------------------------------------- + + { + const toml::value v{ + {"a", 42}, + {"b", "bar.b"}, + {"f", toml::table{{"a", 42}, {"b", "foo.b"}}} + }; + + const auto bar = toml::get(v); + BOOST_TEST(bar.a == 42); + BOOST_TEST(bar.b == "bar.b"); + BOOST_TEST(bar.f.a == 42); + BOOST_TEST(bar.f.b == "foo.b"); + + const toml::value v2(bar); + BOOST_TEST(v2 == v); + } + { + const toml::basic_value v{ + {"a", 42}, + {"b", "bar.b"}, + {"f", toml::table{{"a", 42}, {"b", "foo.b"}}} + }; + + const auto bar = toml::get(v); + BOOST_TEST(bar.a == 42); + BOOST_TEST(bar.b == "bar.b"); + BOOST_TEST(bar.f.a == 42); + BOOST_TEST(bar.f.b == "foo.b"); + + const toml::basic_value v2(bar); + BOOST_TEST(v2 == v); + } +} +#endif // TOML11_WITHOUT_DEFINE_NON_INTRUSIVE diff --git a/external/toml11/tests/test_find.cpp b/external/toml11/tests/test_find.cpp new file mode 100644 index 0000000..944b8e8 --- /dev/null +++ b/external/toml11/tests/test_find.cpp @@ -0,0 +1,827 @@ +#include + +#include "unit_test.hpp" + +#include +#include +#include +#include +#include +#include + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L +#include +#endif + +using test_value_types = std::tuple< + toml::basic_value, + toml::basic_value, + toml::basic_value, + toml::basic_value + >; + +BOOST_AUTO_TEST_CASE(test_find_throws) +{ + // ----------------------------------------------------------------------- + // const-reference version + { + // value is not a table + const toml::value v(true); + BOOST_CHECK_THROW(toml::find(v, "key"), toml::type_error); + } + { + // the value corresponding to the key is not the expected type + const toml::value v{{"key", 42}}; + BOOST_CHECK_THROW(toml::find(v, "key"), toml::type_error); + } + { + // the value corresponding to the key is not found + const toml::value v{{"key", 42}}; + BOOST_CHECK_THROW(toml::find(v, "different_key"), + std::out_of_range); + } + { + // the positive control. + const toml::value v{{"key", 42}}; + BOOST_TEST(42 == toml::find(v, "key")); + } + + // ----------------------------------------------------------------------- + // reference version + { + // value is not a table + toml::value v(true); + BOOST_CHECK_THROW(toml::find(v, "key"), toml::type_error); + } + { + // the value corresponding to the key is not the expected type + toml::value v{{"key", 42}}; + BOOST_CHECK_THROW(toml::find(v, "key"), toml::type_error); + } + { + // the value corresponding to the key is not found + toml::value v{{"key", 42}}; + BOOST_CHECK_THROW(toml::find(v, "different_key"), + std::out_of_range); + } + { + // the positive control. + toml::value v{{"key", 42}}; + BOOST_TEST(42 == toml::find(v, "key")); + } + + // ----------------------------------------------------------------------- + // move version + + { + // value is not a table + toml::value v(true); + BOOST_CHECK_THROW(toml::find(std::move(v), "key"), toml::type_error); + } + { + // the value corresponding to the key is not the expected type + toml::value v{{"key", 42}}; + BOOST_CHECK_THROW(toml::find(std::move(v), "key"), toml::type_error); + } + { + // the value corresponding to the key is not found + toml::value v{{"key", 42}}; + BOOST_CHECK_THROW(toml::find(std::move(v), "different_key"), + std::out_of_range); + } + { + // the positive control. + toml::value v{{"key", 42}}; + BOOST_TEST(42 == toml::find(std::move(v), "key")); + } +} + +BOOST_AUTO_TEST_CASE(test_find_array_throws) +{ + // ----------------------------------------------------------------------- + // const-reference version + { + // value is not an array + const toml::value v(true); + BOOST_CHECK_THROW(toml::find(v, 0), toml::type_error); + } + { + // the value corresponding to the key is not the expected type + const toml::value v{1, 2, 3, 4, 5}; + BOOST_CHECK_THROW(toml::find(v, 0), toml::type_error); + } + { + // the value corresponding to the key is not found + const toml::value v{1, 2, 3, 4, 5}; + BOOST_CHECK_THROW(toml::find(v, 6), std::out_of_range); + } + { + // the positive control. + const toml::value v{1, 2, 3, 4, 5}; + BOOST_TEST(3 == toml::find(v, 2)); + } + + // ----------------------------------------------------------------------- + // non-const reference version + { + // value is not an array + toml::value v(true); + BOOST_CHECK_THROW(toml::find(v, 0), toml::type_error); + } + { + // the value corresponding to the key is not the expected type + toml::value v{1, 2, 3, 4, 5}; + BOOST_CHECK_THROW(toml::find(v, 0), toml::type_error); + } + { + // the value corresponding to the key is not found + toml::value v{1, 2, 3, 4, 5}; + BOOST_CHECK_THROW(toml::find(v, 6), std::out_of_range); + } + { + // the positive control. + toml::value v{1, 2, 3, 4, 5}; + BOOST_TEST(3 == toml::find(v, 2)); + } + + // ----------------------------------------------------------------------- + // move version + { + // value is not an array + toml::value v(true); + BOOST_CHECK_THROW(toml::find(std::move(v), 0), toml::type_error); + } + { + // the value corresponding to the key is not the expected type + toml::value v{1, 2, 3, 4, 5}; + BOOST_CHECK_THROW(toml::find(std::move(v), 0), toml::type_error); + } + { + // the value corresponding to the key is not found + toml::value v{1, 2, 3, 4, 5}; + BOOST_CHECK_THROW(toml::find(std::move(v), 6), std::out_of_range); + } + { + // the positive control. + toml::value v{1, 2, 3, 4, 5}; + BOOST_TEST(3 == toml::find(std::move(v), 2)); + } +} + +BOOST_AUTO_TEST_CASE(test_find_recursive) +{ + // recursively search tables + { + toml::value v{ + {"a", { + {"b", { + {"c", { + {"d", 42} + }} + }} + }} + }; + BOOST_TEST(42 == toml::find(v, "a", "b", "c", "d")); + + // reference that can be used to modify the content + auto& num = toml::find(v, "a", "b", "c", "d"); + num = 54; + BOOST_TEST(54 == toml::find(v, "a", "b", "c", "d")); + + const std::string a("a"), b("b"), c("c"), d("d"); + auto& num2 = toml::find(v, a, b, c, d); + num2 = 42; + BOOST_TEST(42 == toml::find(v, a, b, c, d)); + + auto num3 = toml::find(v, a, "b", c, "d"); + BOOST_TEST(42 == num3); + + auto num4 = toml::find(std::move(v), a, b, c, d); + BOOST_TEST(42 == num4); + } + // recursively search arrays + { + toml::value v{ + toml::array{"array", "of", "string"}, + toml::array{toml::array{1, 2, 3}, toml::array{3.14, 2.71}} + }; + BOOST_TEST("array" == toml::find(v, 0, 0)); + BOOST_TEST("of" == toml::find(v, 0, 1)); + BOOST_TEST("string" == toml::find(v, 0, 2)); + + BOOST_TEST(1 == toml::find(v, 1, 0, 0)); + BOOST_TEST(2 == toml::find(v, 1, 0, 1)); + BOOST_TEST(3 == toml::find(v, 1, 0, 2)); + + BOOST_TEST(3.14 == toml::find(v, 1, 1, 0)); + BOOST_TEST(2.71 == toml::find(v, 1, 1, 1)); + + // reference that can be used to modify the content + auto& num = toml::find(v, 1, 0, 2); + num = 42; + BOOST_TEST( 1 == toml::find(v, 1, 0, 0)); + BOOST_TEST( 2 == toml::find(v, 1, 0, 1)); + BOOST_TEST(42 == toml::find(v, 1, 0, 2)); + + // move value + auto num2 = toml::find(std::move(v), 1, 0, 2); + BOOST_TEST(42 == num2); + } + // recursively search mixtures + { + toml::value v = toml::table{{"array", toml::array{ + toml::array{1, 2, 3}, + toml::array{ + toml::table{{"foo", "bar"}, {"baz", "qux"}}, + toml::table{{"pi", 3.14}, {"e", 2.71}} + }} + }}; + + BOOST_TEST(1 == toml::find(v, "array", 0, 0)); + BOOST_TEST(2 == toml::find(v, "array", 0, 1)); + BOOST_TEST(3 == toml::find(v, "array", 0, 2)); + + BOOST_TEST("bar" == toml::find(v, "array", 1, 0, "foo")); + BOOST_TEST("qux" == toml::find(v, "array", 1, 0, "baz")); + + BOOST_TEST(3.14 == toml::find(v, "array", 1, 1, "pi")); + BOOST_TEST(2.71 == toml::find(v, "array", 1, 1, "e")); + + const std::string ar("array"); + const auto ar_c = "array"; + + const std::string pi("pi"); + const auto pi_c = "pi"; + + BOOST_TEST(3.14 == toml::find(v, ar, 1, 1, "pi")); + BOOST_TEST(3.14 == toml::find(v, ar, 1, 1, pi)); + BOOST_TEST(3.14 == toml::find(v, ar, 1, 1, pi_c)); + + BOOST_TEST(3.14 == toml::find(v, ar_c, 1, 1, "pi")); + BOOST_TEST(3.14 == toml::find(v, ar_c, 1, 1, pi)); + BOOST_TEST(3.14 == toml::find(v, ar_c, 1, 1, pi_c)); + + BOOST_TEST(3.14 == toml::find(v, "array", 1, 1, pi)); + BOOST_TEST(3.14 == toml::find(v, "array", 1, 1, pi_c)); + } +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types) +{ + { + value_type v{{"key", true}}; + BOOST_TEST(true == toml::find(v, "key")); + + toml::find(v, "key") = false; + BOOST_TEST(false == toml::find(v, "key")); + + const auto moved = toml::find(std::move(v), "key"); + BOOST_TEST(false == moved); + } + { + value_type v{{"key", 42}}; + BOOST_TEST(toml::integer(42) == toml::find(v, "key")); + + toml::find(v, "key") = 54; + BOOST_TEST(toml::integer(54) == toml::find(v, "key")); + + const auto moved = toml::find(std::move(v), "key"); + BOOST_TEST(toml::integer(54) == moved); + } + { + value_type v{{"key", 3.14}}; + BOOST_TEST(toml::floating(3.14) == toml::find(v, "key")); + + toml::find(v, "key") = 2.71; + BOOST_TEST(toml::floating(2.71) == toml::find(v, "key")); + + const auto moved = toml::find(std::move(v), "key"); + BOOST_TEST(toml::floating(2.71) == moved); + } + { + value_type v{{"key", "foo"}}; + BOOST_TEST(toml::string("foo", toml::string_t::basic) == + toml::find(v, "key")); + + toml::find(v, "key").str += "bar"; + BOOST_TEST(toml::string("foobar", toml::string_t::basic) == + toml::find(v, "key")); + + const auto moved = toml::find(std::move(v), "key"); + BOOST_TEST(toml::string("foobar", toml::string_t::basic) == moved); + } + { + value_type v{{"key", value_type("foo", toml::string_t::literal)}}; + BOOST_TEST(toml::string("foo", toml::string_t::literal) == + toml::find(v, "key")); + + toml::find(v, "key").str += "bar"; + BOOST_TEST(toml::string("foobar", toml::string_t::literal) == + toml::find(v, "key")); + + const auto moved = toml::find(std::move(v), "key"); + BOOST_TEST(toml::string("foobar", toml::string_t::literal) == moved); + } + { + toml::local_date d(2018, toml::month_t::Apr, 22); + value_type v{{"key", d}}; + BOOST_CHECK(d == toml::find(v, "key")); + + toml::find(v, "key").year = 2017; + d.year = 2017; + BOOST_CHECK(d == toml::find(v, "key")); + + const auto moved = toml::find(std::move(v), "key"); + BOOST_CHECK(d == moved); + } + { + toml::local_time t(12, 30, 45); + value_type v{{"key", t}}; + BOOST_CHECK(t == toml::find(v, "key")); + + toml::find(v, "key").hour = 9; + t.hour = 9; + BOOST_CHECK(t == toml::find(v, "key")); + + const auto moved = toml::find(std::move(v), "key"); + BOOST_CHECK(t == moved); + } + { + toml::local_datetime dt(toml::local_date(2018, toml::month_t::Apr, 22), + toml::local_time(12, 30, 45)); + value_type v{{"key", dt}}; + BOOST_CHECK(dt == toml::find(v, "key")); + + toml::find(v, "key").date.year = 2017; + dt.date.year = 2017; + BOOST_CHECK(dt == toml::find(v, "key")); + + const auto moved = toml::find(std::move(v), "key"); + BOOST_CHECK(dt == moved); + } + { + toml::offset_datetime dt(toml::local_datetime( + toml::local_date(2018, toml::month_t::Apr, 22), + toml::local_time(12, 30, 45)), toml::time_offset(9, 0)); + value_type v{{"key", dt}}; + BOOST_CHECK(dt == toml::find(v, "key")); + + toml::find(v, "key").date.year = 2017; + dt.date.year = 2017; + BOOST_CHECK(dt == toml::find(v, "key")); + + const auto moved = toml::find(std::move(v), "key"); + BOOST_CHECK(dt == moved); + } + { + typename value_type::array_type vec; + vec.push_back(value_type(42)); + vec.push_back(value_type(54)); + value_type v{{"key", vec}}; + + const bool result1 = (vec == toml::find(v, "key")); + BOOST_CHECK(result1); + + toml::find(v, "key").push_back(value_type(123)); + vec.push_back(value_type(123)); + + const bool result2 = (vec == toml::find(v, "key")); + BOOST_CHECK(result2); + + const auto moved = toml::find(std::move(v), "key"); + const bool result3 = (vec == moved); + BOOST_CHECK(result3); + } + { + typename value_type::table_type tab; + tab["key1"] = value_type(42); + tab["key2"] = value_type(3.14); + value_type v{{"key", tab}}; + const bool result1 = (tab == toml::find(v, "key")); + BOOST_CHECK(result1); + + toml::find(v, "key")["key3"] = value_type(123); + tab["key3"] = value_type(123); + const bool result2 = (tab == toml::find(v, "key")); + BOOST_CHECK(result2); + + const auto moved = toml::find(std::move(v), "key"); + const bool result3 = (tab == moved); + BOOST_CHECK(result3); + } + { + value_type v1(42); + value_type v{{"key", v1}}; + BOOST_CHECK(v1 == toml::find(v, "key")); + + value_type v2(54); + toml::find(v, "key") = v2; + BOOST_CHECK(v2 == toml::find(v, "key")); + + const auto moved = toml::find(std::move(v), "key"); + BOOST_CHECK(v2 == moved); + } +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_integer_type, value_type, test_value_types) +{ + { + value_type v{{"key", 42}}; + BOOST_TEST(int(42) == toml::find(v, "key")); + BOOST_TEST(short(42) == toml::find(v, "key")); + BOOST_TEST(char(42) == toml::find(v, "key")); + BOOST_TEST(unsigned(42) == toml::find(v, "key")); + BOOST_TEST(long(42) == toml::find(v, "key")); + BOOST_TEST(std::int64_t(42) == toml::find(v, "key")); + BOOST_TEST(std::uint64_t(42) == toml::find(v, "key")); + BOOST_TEST(std::int16_t(42) == toml::find(v, "key")); + BOOST_TEST(std::uint16_t(42) == toml::find(v, "key")); + BOOST_TEST(std::uint16_t(42) == toml::find(std::move(v), "key")); + } +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_floating_type, value_type, test_value_types) +{ + { + value_type v{{"key", 3.14}}; + const double ref(3.14); + BOOST_TEST(static_cast(ref) == toml::find(v, "key")); + BOOST_TEST( ref == toml::find(v, "key")); + BOOST_TEST(static_cast(ref) == toml::find(v, "key")); + BOOST_TEST(static_cast(ref) == toml::find(std::move(v), "key")); + } +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_string_type, value_type, test_value_types) +{ + { + value_type v{{"key", toml::string("foo", toml::string_t::basic)}}; + BOOST_TEST("foo" == toml::find(v, "key")); + toml::find(v, "key") += "bar"; + BOOST_TEST("foobar" == toml::find(v, "key")); + } + { + value_type v{{"key", toml::string("foo", toml::string_t::literal)}}; + BOOST_TEST("foo" == toml::find(v, "key")); + toml::find(v, "key") += "bar"; + BOOST_TEST("foobar" == toml::find(v, "key")); + } + { + value_type v{{"key", toml::string("foo", toml::string_t::literal)}}; + const auto moved = toml::find(std::move(v), "key"); + BOOST_TEST("foo" == moved); + } + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L + { + value_type v{{"key", toml::string("foo", toml::string_t::basic)}}; + BOOST_TEST("foo" == toml::find(v, "key")); + } + { + value_type v{{"key", toml::string("foo", toml::string_t::literal)}}; + BOOST_TEST("foo" == toml::find(v, "key")); + } +#endif +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_array, value_type, test_value_types) +{ + value_type v{{"key", {42, 54, 69, 72}}}; + + const std::vector vec = toml::find>(v, "key"); + const std::list lst = toml::find>(v, "key"); + const std::deque deq = toml::find>(v, "key"); + + BOOST_TEST(42 == vec.at(0)); + BOOST_TEST(54 == vec.at(1)); + BOOST_TEST(69 == vec.at(2)); + BOOST_TEST(72 == vec.at(3)); + + std::list::const_iterator iter = lst.begin(); + BOOST_TEST(static_cast(42) == *(iter++)); + BOOST_TEST(static_cast(54) == *(iter++)); + BOOST_TEST(static_cast(69) == *(iter++)); + BOOST_TEST(static_cast(72) == *(iter++)); + + BOOST_TEST(static_cast(42) == deq.at(0)); + BOOST_TEST(static_cast(54) == deq.at(1)); + BOOST_TEST(static_cast(69) == deq.at(2)); + BOOST_TEST(static_cast(72) == deq.at(3)); + + std::array ary = toml::find>(v, "key"); + BOOST_TEST(42 == ary.at(0)); + BOOST_TEST(54 == ary.at(1)); + BOOST_TEST(69 == ary.at(2)); + BOOST_TEST(72 == ary.at(3)); + + std::tuple tpl = + toml::find>(v, "key"); + BOOST_TEST( 42 == std::get<0>(tpl)); + BOOST_TEST(static_cast(54) == std::get<1>(tpl)); + BOOST_TEST(static_cast(69) == std::get<2>(tpl)); + BOOST_TEST(static_cast(72) == std::get<3>(tpl)); + + value_type p{{"key", {3.14, 2.71}}}; + std::pair pr = toml::find >(p, "key"); + BOOST_TEST(3.14 == pr.first); + BOOST_TEST(2.71 == pr.second); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_move_toml_array, value_type, test_value_types) +{ + value_type v1{{"key", {42, 54, 69, 72}}}; + value_type v2{{"key", {42, 54, 69, 72}}}; + value_type v3{{"key", {42, 54, 69, 72}}}; + value_type v4{{"key", {42, 54, 69, 72}}}; + value_type v5{{"key", {42, 54, 69, 72}}}; + + const std::vector vec = toml::find>(std::move(v1), "key"); + const std::list lst = toml::find>(std::move(v2), "key"); + const std::deque deq = toml::find>(std::move(v3), "key"); + + BOOST_TEST(42 == vec.at(0)); + BOOST_TEST(54 == vec.at(1)); + BOOST_TEST(69 == vec.at(2)); + BOOST_TEST(72 == vec.at(3)); + + std::list::const_iterator iter = lst.begin(); + BOOST_TEST(static_cast(42) == *(iter++)); + BOOST_TEST(static_cast(54) == *(iter++)); + BOOST_TEST(static_cast(69) == *(iter++)); + BOOST_TEST(static_cast(72) == *(iter++)); + + BOOST_TEST(static_cast(42) == deq.at(0)); + BOOST_TEST(static_cast(54) == deq.at(1)); + BOOST_TEST(static_cast(69) == deq.at(2)); + BOOST_TEST(static_cast(72) == deq.at(3)); + + std::array ary = toml::find>(std::move(v4), "key"); + BOOST_TEST(42 == ary.at(0)); + BOOST_TEST(54 == ary.at(1)); + BOOST_TEST(69 == ary.at(2)); + BOOST_TEST(72 == ary.at(3)); + + std::tuple tpl = + toml::find>(std::move(v5), "key"); + BOOST_TEST( 42 == std::get<0>(tpl)); + BOOST_TEST(static_cast(54) == std::get<1>(tpl)); + BOOST_TEST(static_cast(69) == std::get<2>(tpl)); + BOOST_TEST(static_cast(72) == std::get<3>(tpl)); + + value_type p{{"key", {3.14, 2.71}}}; + std::pair pr = toml::find >(std::move(p), "key"); + BOOST_TEST(3.14 == pr.first); + BOOST_TEST(2.71 == pr.second); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_array_of_array, value_type, test_value_types) +{ + value_type v1{42, 54, 69, 72}; + value_type v2{"foo", "bar", "baz"}; + value_type v{{"key", {v1, v2}}}; + + std::pair, std::vector> p = + toml::find, std::vector>>(v, "key"); + + BOOST_TEST(p.first.at(0) == 42); + BOOST_TEST(p.first.at(1) == 54); + BOOST_TEST(p.first.at(2) == 69); + BOOST_TEST(p.first.at(3) == 72); + + BOOST_TEST(p.second.at(0) == "foo"); + BOOST_TEST(p.second.at(1) == "bar"); + BOOST_TEST(p.second.at(2) == "baz"); + + std::tuple, std::vector> t = + toml::find, std::vector>>(v, "key"); + + BOOST_TEST(std::get<0>(t).at(0) == 42); + BOOST_TEST(std::get<0>(t).at(1) == 54); + BOOST_TEST(std::get<0>(t).at(2) == 69); + BOOST_TEST(std::get<0>(t).at(3) == 72); + + BOOST_TEST(std::get<1>(t).at(0) == "foo"); + BOOST_TEST(std::get<1>(t).at(1) == "bar"); + BOOST_TEST(std::get<1>(t).at(2) == "baz"); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_move_toml_array_of_array, value_type, test_value_types) +{ + value_type a1{42, 54, 69, 72}; + value_type a2{"foo", "bar", "baz"}; + value_type v1{{"key", {a1, a2}}}; + value_type v2{{"key", {a1, a2}}}; + + std::pair, std::vector> p = + toml::find, std::vector>>(std::move(v1), "key"); + + BOOST_TEST(p.first.at(0) == 42); + BOOST_TEST(p.first.at(1) == 54); + BOOST_TEST(p.first.at(2) == 69); + BOOST_TEST(p.first.at(3) == 72); + + BOOST_TEST(p.second.at(0) == "foo"); + BOOST_TEST(p.second.at(1) == "bar"); + BOOST_TEST(p.second.at(2) == "baz"); + + std::tuple, std::vector> t = + toml::find, std::vector>>(std::move(v2), "key"); + + BOOST_TEST(std::get<0>(t).at(0) == 42); + BOOST_TEST(std::get<0>(t).at(1) == 54); + BOOST_TEST(std::get<0>(t).at(2) == 69); + BOOST_TEST(std::get<0>(t).at(3) == 72); + + BOOST_TEST(std::get<1>(t).at(0) == "foo"); + BOOST_TEST(std::get<1>(t).at(1) == "bar"); + BOOST_TEST(std::get<1>(t).at(2) == "baz"); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_table, value_type, test_value_types) +{ + { + value_type v1{{"key", { + {"key1", 1}, {"key2", 2}, {"key3", 3}, {"key4", 4} + }}}; + const auto v = toml::find>(v1, "key"); + BOOST_TEST(v.at("key1") == 1); + BOOST_TEST(v.at("key2") == 2); + BOOST_TEST(v.at("key3") == 3); + BOOST_TEST(v.at("key4") == 4); + } + { + value_type v1{{"key", { + {"key1", 1}, {"key2", 2}, {"key3", 3}, {"key4", 4} + }}}; + const auto v = toml::find>(std::move(v1), "key"); + BOOST_TEST(v.at("key1") == 1); + BOOST_TEST(v.at("key2") == 2); + BOOST_TEST(v.at("key3") == 3); + BOOST_TEST(v.at("key4") == 4); + } +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_date, value_type, test_value_types) +{ + { + value_type v1{{"key", toml::local_date{2018, toml::month_t::Apr, 1}}}; + const auto date = std::chrono::system_clock::to_time_t( + toml::find(v1, "key")); + + std::tm t; + t.tm_year = 2018 - 1900; + t.tm_mon = 4 - 1; + t.tm_mday = 1; + t.tm_hour = 0; + t.tm_min = 0; + t.tm_sec = 0; + t.tm_isdst = -1; + const auto c = std::mktime(&t); + BOOST_TEST(c == date); + } + { + value_type v1{{"key", toml::local_date{2018, toml::month_t::Apr, 1}}}; + const auto date = std::chrono::system_clock::to_time_t( + toml::find(std::move(v1), "key")); + + std::tm t; + t.tm_year = 2018 - 1900; + t.tm_mon = 4 - 1; + t.tm_mday = 1; + t.tm_hour = 0; + t.tm_min = 0; + t.tm_sec = 0; + t.tm_isdst = -1; + const auto c = std::mktime(&t); + BOOST_TEST(c == date); + } +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_time, value_type, test_value_types) +{ + { + value_type v1{{"key", toml::local_time{12, 30, 45}}}; + const auto time = toml::find(v1, "key"); + BOOST_CHECK(time == std::chrono::hours(12) + + std::chrono::minutes(30) + std::chrono::seconds(45)); + } + { + value_type v1{{"key", toml::local_time{12, 30, 45}}}; + const auto time = toml::find(std::move(v1), "key"); + BOOST_CHECK(time == std::chrono::hours(12) + + std::chrono::minutes(30) + std::chrono::seconds(45)); + } +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_datetime, value_type, test_value_types) +{ + { + value_type v1{{"key", toml::local_datetime( + toml::local_date{2018, toml::month_t::Apr, 1}, + toml::local_time{12, 30, 45})}}; + + const auto date = std::chrono::system_clock::to_time_t( + toml::find(v1, "key")); + std::tm t; + t.tm_year = 2018 - 1900; + t.tm_mon = 4 - 1; + t.tm_mday = 1; + t.tm_hour = 12; + t.tm_min = 30; + t.tm_sec = 45; + t.tm_isdst = -1; + const auto c = std::mktime(&t); + BOOST_TEST(c == date); + } + { + value_type v1{{"key", toml::local_datetime( + toml::local_date{2018, toml::month_t::Apr, 1}, + toml::local_time{12, 30, 45})}}; + + const auto date = std::chrono::system_clock::to_time_t( + toml::find(std::move(v1), "key")); + std::tm t; + t.tm_year = 2018 - 1900; + t.tm_mon = 4 - 1; + t.tm_mday = 1; + t.tm_hour = 12; + t.tm_min = 30; + t.tm_sec = 45; + t.tm_isdst = -1; + const auto c = std::mktime(&t); + BOOST_TEST(c == date); + } +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_offset_datetime, value_type, test_value_types) +{ + { + value_type v1{{"key", toml::offset_datetime( + toml::local_date{2018, toml::month_t::Apr, 1}, + toml::local_time{12, 30, 0}, + toml::time_offset{9, 0})}}; + // 2018-04-01T12:30:00+09:00 + // == 2018-04-01T03:30:00Z + + const auto date = toml::find(v1, "key"); + const auto timet = std::chrono::system_clock::to_time_t(date); + + // get time_t as gmtime (2018-04-01T03:30:00Z) + const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! + BOOST_CHECK(tmp); + const auto tm = *tmp; + BOOST_TEST(tm.tm_year + 1900 == 2018); + BOOST_TEST(tm.tm_mon + 1 == 4); + BOOST_TEST(tm.tm_mday == 1); + BOOST_TEST(tm.tm_hour == 3); + BOOST_TEST(tm.tm_min == 30); + BOOST_TEST(tm.tm_sec == 0); + } + + { + value_type v1{{"key", toml::offset_datetime( + toml::local_date{2018, toml::month_t::Apr, 1}, + toml::local_time{12, 30, 0}, + toml::time_offset{-8, 0})}}; + // 2018-04-01T12:30:00-08:00 + // == 2018-04-01T20:30:00Z + + const auto date = toml::find(v1, "key"); + const auto timet = std::chrono::system_clock::to_time_t(date); + + // get time_t as gmtime (2018-04-01T03:30:00Z) + const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! + BOOST_CHECK(tmp); + const auto tm = *tmp; + BOOST_TEST(tm.tm_year + 1900 == 2018); + BOOST_TEST(tm.tm_mon + 1 == 4); + BOOST_TEST(tm.tm_mday == 1); + BOOST_TEST(tm.tm_hour == 20); + BOOST_TEST(tm.tm_min == 30); + BOOST_TEST(tm.tm_sec == 0); + } + + { + value_type v1{{"key", toml::offset_datetime( + toml::local_date{2018, toml::month_t::Apr, 1}, + toml::local_time{12, 30, 0}, + toml::time_offset{-8, 0})}}; + // 2018-04-01T12:30:00-08:00 + // == 2018-04-01T20:30:00Z + + const auto date = toml::find(std::move(v1), "key"); + const auto timet = std::chrono::system_clock::to_time_t(date); + + // get time_t as gmtime (2018-04-01T03:30:00Z) + const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! + BOOST_CHECK(tmp); + const auto tm = *tmp; + BOOST_TEST(tm.tm_year + 1900 == 2018); + BOOST_TEST(tm.tm_mon + 1 == 4); + BOOST_TEST(tm.tm_mday == 1); + BOOST_TEST(tm.tm_hour == 20); + BOOST_TEST(tm.tm_min == 30); + BOOST_TEST(tm.tm_sec == 0); + } +} diff --git a/external/toml11/tests/test_find_or.cpp b/external/toml11/tests/test_find_or.cpp new file mode 100644 index 0000000..8348f2f --- /dev/null +++ b/external/toml11/tests/test_find_or.cpp @@ -0,0 +1,538 @@ +#include + +#include "unit_test.hpp" + +#include +#include +#include +#include +#include +#include + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L +#include +#endif + +using test_value_types = std::tuple< + toml::basic_value, + toml::basic_value, + toml::basic_value, + toml::basic_value +>; + +namespace test +{ +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const std::vector& v) +{ + os << "[ "; + for(const auto& i : v) {os << i << ' ';} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const std::deque& v) +{ + os << "[ "; + for(const auto& i : v) {os << i << ' ';} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const std::list& v) +{ + os << "[ "; + for(const auto& i : v) {os << i << ' ';} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + const std::map& v) +{ + os << "[ "; + for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + const std::unordered_map& v) +{ + os << "[ "; + for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";} + os << ']'; + return os; +} +} // test + +#define TOML11_TEST_FIND_OR_EXACT(toml_type, init_expr, opt_expr)\ + { \ + using namespace test; \ + const toml::toml_type init init_expr ; \ + const toml::toml_type opt opt_expr ; \ + const value_type v{{"key", init}}; \ + BOOST_TEST(init != opt); \ + BOOST_TEST(init == toml::find_or(v, "key", opt)); \ + } \ + /**/ + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_exact, value_type, test_value_types) +{ + TOML11_TEST_FIND_OR_EXACT(boolean, ( true), (false)) + TOML11_TEST_FIND_OR_EXACT(integer, ( 42), ( 54)) + TOML11_TEST_FIND_OR_EXACT(floating, ( 3.14), ( 2.71)) + TOML11_TEST_FIND_OR_EXACT(string, ("foo"), ("bar")) + TOML11_TEST_FIND_OR_EXACT(local_time, (12, 30, 45), (6, 0, 30)) + TOML11_TEST_FIND_OR_EXACT(local_date, (2019, toml::month_t::Apr, 1), + (1999, toml::month_t::Jan, 2)) + TOML11_TEST_FIND_OR_EXACT(local_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) + ) + TOML11_TEST_FIND_OR_EXACT(offset_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) + ) + { + const typename value_type::array_type init{1,2,3,4,5}; + const typename value_type::array_type opt {6,7,8,9,10}; + const value_type v{{"key", init}}; + BOOST_TEST(init != opt); + BOOST_TEST(init == toml::find_or(v, "key", opt)); + } + { + const typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; + const typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}}; + const value_type v{{"key", init}}; + BOOST_TEST(init != opt); + BOOST_TEST(init == toml::find_or(v, "key", opt)); + } +} +#undef TOML11_TEST_FIND_OR_EXACT + +#define TOML11_TEST_FIND_OR_MOVE(toml_type, init_expr, opt_expr) \ + { \ + using namespace test; \ + const toml::toml_type init init_expr ; \ + toml::toml_type opt opt_expr ; \ + value_type v{{"key", init}}; \ + BOOST_TEST(init != opt); \ + const auto moved = toml::find_or(std::move(v), "key", std::move(opt));\ + BOOST_TEST(init == moved); \ + } \ + /**/ + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_move, value_type, test_value_types) +{ + TOML11_TEST_FIND_OR_MOVE(boolean, ( true), (false)) + TOML11_TEST_FIND_OR_MOVE(integer, ( 42), ( 54)) + TOML11_TEST_FIND_OR_MOVE(floating, ( 3.14), ( 2.71)) + TOML11_TEST_FIND_OR_MOVE(string, ("foo"), ("bar")) + TOML11_TEST_FIND_OR_MOVE(local_time, (12, 30, 45), (6, 0, 30)) + TOML11_TEST_FIND_OR_MOVE(local_date, (2019, toml::month_t::Apr, 1), + (1999, toml::month_t::Jan, 2)) + TOML11_TEST_FIND_OR_MOVE(local_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) + ) + TOML11_TEST_FIND_OR_MOVE(offset_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) + ) + { + typename value_type::array_type init{1,2,3,4,5}; + typename value_type::array_type opt {6,7,8,9,10}; + value_type v{{"key", init}}; + BOOST_TEST(init != opt); + const auto moved = toml::find_or(std::move(v), "key", std::move(opt)); + BOOST_TEST(init == moved); + } + { + typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; + typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}}; + value_type v{{"key", init}}; + BOOST_TEST(init != opt); + const auto moved = toml::find_or(std::move(v), "key", std::move(opt)); + BOOST_TEST(init == moved); + } +} +#undef TOML11_TEST_FIND_OR_MOVE + + +#define TOML11_TEST_FIND_OR_MODIFY(toml_type, init_expr, opt_expr)\ + { \ + using namespace test; \ + const toml::toml_type init init_expr ; \ + toml::toml_type opt1 opt_expr ; \ + toml::toml_type opt2 opt_expr ; \ + value_type v{{"key", init}}; \ + BOOST_TEST(init != opt1); \ + toml::find_or(v, "key", opt2) = opt1; \ + BOOST_TEST(opt1 == toml::find(v, "key"));\ + } \ + /**/ +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_modify, value_type, test_value_types) +{ + TOML11_TEST_FIND_OR_MODIFY(boolean, ( true), (false)) + TOML11_TEST_FIND_OR_MODIFY(integer, ( 42), ( 54)) + TOML11_TEST_FIND_OR_MODIFY(floating, ( 3.14), ( 2.71)) + TOML11_TEST_FIND_OR_MODIFY(string, ("foo"), ("bar")) + TOML11_TEST_FIND_OR_MODIFY(local_time, (12, 30, 45), (6, 0, 30)) + TOML11_TEST_FIND_OR_MODIFY(local_date, (2019, toml::month_t::Apr, 1), + (1999, toml::month_t::Jan, 2)) + TOML11_TEST_FIND_OR_MODIFY(local_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) + ) + TOML11_TEST_FIND_OR_MODIFY(offset_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) + ) + { + typename value_type::array_type init{1,2,3,4,5}; + typename value_type::array_type opt1{6,7,8,9,10}; + typename value_type::array_type opt2{6,7,8,9,10}; + BOOST_TEST(init != opt1); + value_type v{{"key", init}}; + toml::find_or(v, "key", opt2) = opt1; + BOOST_TEST(opt1 == toml::find(v, "key")); + } + { + typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; + typename value_type::table_type opt1{{"key1", 54}, {"key2", "bar"}}; + typename value_type::table_type opt2{{"key1", 54}, {"key2", "bar"}}; + value_type v{{"key", init}}; + BOOST_TEST(init != opt1); + toml::find_or(v, "key", opt2) = opt1; + BOOST_TEST(opt1 == toml::find(v, "key")); + } +} +#undef TOML11_TEST_FIND_OR_MODIFY + +#define TOML11_TEST_FIND_OR_FALLBACK(init_type, opt_type) \ + { \ + using namespace test; \ + value_type v(init_type); \ + BOOST_TEST(opt_type == toml::find_or(v, "key", opt_type));\ + } \ + /**/ + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_fallback, value_type, test_value_types) +{ + const toml::boolean boolean (true); + const toml::integer integer (42); + const toml::floating floating (3.14); + const toml::string string ("foo"); + const toml::local_time local_time (12, 30, 45); + const toml::local_date local_date (2019, toml::month_t::Apr, 1); + const toml::local_datetime local_datetime ( + toml::local_date(2019, toml::month_t::Apr, 1), + toml::local_time(12, 30, 45)); + const toml::offset_datetime offset_datetime( + toml::local_date(2019, toml::month_t::Apr, 1), + toml::local_time(12, 30, 45), toml::time_offset( 9, 0)); + + using array_type = typename value_type::array_type; + using table_type = typename value_type::table_type; + const array_type array{1, 2, 3, 4, 5}; + const table_type table{{"key1", 42}, {"key2", "foo"}}; + + TOML11_TEST_FIND_OR_FALLBACK(boolean, integer ); + TOML11_TEST_FIND_OR_FALLBACK(boolean, floating ); + TOML11_TEST_FIND_OR_FALLBACK(boolean, string ); + TOML11_TEST_FIND_OR_FALLBACK(boolean, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(boolean, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(boolean, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(boolean, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(boolean, array ); + TOML11_TEST_FIND_OR_FALLBACK(boolean, table ); + + TOML11_TEST_FIND_OR_FALLBACK(integer, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(integer, floating ); + TOML11_TEST_FIND_OR_FALLBACK(integer, string ); + TOML11_TEST_FIND_OR_FALLBACK(integer, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(integer, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(integer, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(integer, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(integer, array ); + TOML11_TEST_FIND_OR_FALLBACK(integer, table ); + + TOML11_TEST_FIND_OR_FALLBACK(floating, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(floating, integer ); + TOML11_TEST_FIND_OR_FALLBACK(floating, string ); + TOML11_TEST_FIND_OR_FALLBACK(floating, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(floating, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(floating, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(floating, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(floating, array ); + TOML11_TEST_FIND_OR_FALLBACK(floating, table ); + + TOML11_TEST_FIND_OR_FALLBACK(string, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(string, integer ); + TOML11_TEST_FIND_OR_FALLBACK(string, floating ); + TOML11_TEST_FIND_OR_FALLBACK(string, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(string, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(string, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(string, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(string, array ); + TOML11_TEST_FIND_OR_FALLBACK(string, table ); + + TOML11_TEST_FIND_OR_FALLBACK(local_time, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(local_time, integer ); + TOML11_TEST_FIND_OR_FALLBACK(local_time, floating ); + TOML11_TEST_FIND_OR_FALLBACK(local_time, string ); + TOML11_TEST_FIND_OR_FALLBACK(local_time, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(local_time, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(local_time, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(local_time, array ); + TOML11_TEST_FIND_OR_FALLBACK(local_time, table ); + + TOML11_TEST_FIND_OR_FALLBACK(local_date, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(local_date, integer ); + TOML11_TEST_FIND_OR_FALLBACK(local_date, floating ); + TOML11_TEST_FIND_OR_FALLBACK(local_date, string ); + TOML11_TEST_FIND_OR_FALLBACK(local_date, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(local_date, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(local_date, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(local_date, array ); + TOML11_TEST_FIND_OR_FALLBACK(local_date, table ); + + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, integer ); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, floating ); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, string ); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, array ); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, table ); + + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, integer ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, floating ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, string ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, array ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, table ); + + TOML11_TEST_FIND_OR_FALLBACK(array, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(array, integer ); + TOML11_TEST_FIND_OR_FALLBACK(array, floating ); + TOML11_TEST_FIND_OR_FALLBACK(array, string ); + TOML11_TEST_FIND_OR_FALLBACK(array, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(array, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(array, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(array, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(array, table ); + + TOML11_TEST_FIND_OR_FALLBACK(table, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(table, integer ); + TOML11_TEST_FIND_OR_FALLBACK(table, floating ); + TOML11_TEST_FIND_OR_FALLBACK(table, string ); + TOML11_TEST_FIND_OR_FALLBACK(table, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(table, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(table, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(table, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(table, array ); +} +#undef TOML11_TEST_FIND_OR_FALLBACK + +BOOST_AUTO_TEST_CASE(test_find_or_integer) +{ + { + toml::value v{{"num", 42}}; + BOOST_TEST(42u == toml::find_or(v, "num", 0u)); + BOOST_TEST(0u == toml::find_or(v, "foo", 0u)); + } + { + toml::value v{{"num", 42}}; + const auto moved = toml::find_or(std::move(v), "num", 0u); + BOOST_TEST(42u == moved); + } + { + toml::value v{{"num", 42}}; + const auto moved = toml::find_or(std::move(v), "foo", 0u); + BOOST_TEST(0u == moved); + } +} + +BOOST_AUTO_TEST_CASE(test_find_or_floating) +{ + { + toml::value v1{{"key", 42}}; + toml::value v2{{"key", 3.14}}; + BOOST_TEST(2.71f == toml::find_or(v1, "key", 2.71f)); + const double ref(3.14); + BOOST_TEST(static_cast(ref) == toml::find_or(v2, "key", 2.71f)); + } + { + toml::value v1{{"key", 42}}; + toml::value v2{{"key", 3.14}}; + const auto moved1 = toml::find_or(std::move(v1), "key", 2.71f); + const auto moved2 = toml::find_or(std::move(v2), "key", 2.71f); + BOOST_TEST(2.71f == moved1); + const double ref(3.14); + BOOST_TEST(static_cast(ref) == moved2); + } +} + +BOOST_AUTO_TEST_CASE(test_find_or_string) +{ + { + toml::value v1 = toml::table{{"key", "foobar"}}; + toml::value v2 = toml::table{{"key", 42}}; + + std::string s1("bazqux"); + const std::string s2("bazqux"); + + BOOST_TEST("foobar" == toml::find_or(v1, "key", s1)); + BOOST_TEST("bazqux" == toml::find_or(v2, "key", s1)); + + std::string& v1r = toml::find_or(v1, "key", s1); + std::string& s1r = toml::find_or(v2, "key", s1); + + BOOST_TEST("foobar" == v1r); + BOOST_TEST("bazqux" == s1r); + + BOOST_TEST("foobar" == toml::find_or(v1, "key", s2)); + BOOST_TEST("bazqux" == toml::find_or(v2, "key", s2)); + + BOOST_TEST("foobar" == toml::find_or(std::move(v1), "key", std::move(s1))); + s1 = "bazqux"; // restoring moved value + BOOST_TEST("bazqux" == toml::find_or(std::move(v2), "key", std::move(s1))); + } + { + toml::value v1 = toml::table{{"key", "foobar"}}; + toml::value v2 = toml::table{{"key", 42}}; + + std::string s1("bazqux"); + + const auto moved1 = toml::find_or(std::move(v1), "key", s1); + const auto moved2 = toml::find_or(std::move(v2), "key", s1); + + BOOST_TEST("foobar" == moved1); + BOOST_TEST("bazqux" == moved2); + } + { + toml::value v1 = toml::table{{"key", "foobar"}}; + toml::value v2 = toml::table{{"key", 42}}; + + std::string s1("bazqux"); + std::string s2("bazqux"); + + const auto moved1 = toml::find_or(std::move(v1), "key", std::move(s1)); + const auto moved2 = toml::find_or(std::move(v2), "key", std::move(s2)); + + BOOST_TEST("foobar" == moved1); + BOOST_TEST("bazqux" == moved2); + } + + // string literal + { + toml::value v1 = toml::table{{"key", "foobar"}}; + toml::value v2 = toml::table{{"key",42}}; + + BOOST_TEST("foobar" == toml::find_or(v1, "key", "bazqux")); + BOOST_TEST("bazqux" == toml::find_or(v2, "key", "bazqux")); + + const char* lit = "bazqux"; + BOOST_TEST("foobar" == toml::find_or(v1, "key", lit)); + BOOST_TEST("bazqux" == toml::find_or(v2, "key", lit)); + } + { + toml::value v1 = toml::table{{"key", "foobar"}}; + toml::value v2 = toml::table{{"key",42}}; + + const auto moved1 = toml::find_or(std::move(v1), "key", "bazqux"); + const auto moved2 = toml::find_or(std::move(v2), "key", "bazqux"); + + BOOST_TEST("foobar" == moved1); + BOOST_TEST("bazqux" == moved2); + } + { + toml::value v1 = toml::table{{"key", "foobar"}}; + toml::value v2 = toml::table{{"key",42}}; + + const char* lit = "bazqux"; + const auto moved1 = toml::find_or(std::move(v1), "key", lit); + const auto moved2 = toml::find_or(std::move(v2), "key", lit); + + BOOST_TEST("foobar" == moved1); + BOOST_TEST("bazqux" == moved2); + } + +} + +BOOST_AUTO_TEST_CASE(test_find_or_map) +{ + using map_type = std::map; + { + const toml::value v1{ + {"key", {{"key", "value"}}} + }; + + const auto key = toml::find_or(v1, "key", map_type{}); + const auto key2 = toml::find_or(v1, "key2", map_type{}); + + BOOST_TEST(!key.empty()); + BOOST_TEST(key2.empty()); + + BOOST_TEST(key.size() == 1u); + BOOST_TEST(key.at("key") == "value"); + } + { + toml::value v1{ + {"key", {{"key", "value"}}} + }; + + const auto key = toml::find_or(v1, "key", map_type{}); + const auto key2 = toml::find_or(v1, "key2", map_type{}); + + BOOST_TEST(!key.empty()); + BOOST_TEST(key2.empty()); + + BOOST_TEST(key.size() == 1u); + BOOST_TEST(key.at("key") == "value"); + } + + { + toml::value v1{ + {"key", {{"key", "value"}}} + }; + toml::value v2(v1); + + const auto key = toml::find_or(std::move(v1), "key", map_type{}); + const auto key2 = toml::find_or(std::move(v2), "key2", map_type{}); + + BOOST_TEST(!key.empty()); + BOOST_TEST(key2.empty()); + + BOOST_TEST(key.size() == 1u); + BOOST_TEST(key.at("key") == "value"); + } + { + toml::value v1{ + {"key", {{"key", "value"}}} + }; + toml::value v2(v1); + + const auto key = toml::find_or(std::move(v1), "key", map_type{}); + const auto key2 = toml::find_or(std::move(v2), "key2", map_type{}); + + BOOST_TEST(!key.empty()); + BOOST_TEST(key2.empty()); + + BOOST_TEST(key.size() == 1u); + BOOST_TEST(key.at("key") == "value"); + } +} diff --git a/external/toml11/tests/test_find_or_recursive.cpp b/external/toml11/tests/test_find_or_recursive.cpp new file mode 100644 index 0000000..1f2f480 --- /dev/null +++ b/external/toml11/tests/test_find_or_recursive.cpp @@ -0,0 +1,393 @@ +#include + +#include "unit_test.hpp" + +#include +#include +#include +#include +#include +#include + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L +#include +#endif + +using test_value_types = std::tuple< + toml::basic_value, + toml::basic_value, + toml::basic_value, + toml::basic_value +>; + +namespace test +{ +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const std::vector& v) +{ + os << "[ "; + for(const auto& i : v) {os << i << ' ';} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const std::deque& v) +{ + os << "[ "; + for(const auto& i : v) {os << i << ' ';} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const std::list& v) +{ + os << "[ "; + for(const auto& i : v) {os << i << ' ';} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + const std::map& v) +{ + os << "[ "; + for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + const std::unordered_map& v) +{ + os << "[ "; + for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";} + os << ']'; + return os; +} +} // test + +#define TOML11_TEST_FIND_OR_EXACT(toml_type, init_expr, opt_expr) \ + { \ + using namespace test; \ + const toml::toml_type init init_expr ; \ + const toml::toml_type opt opt_expr ; \ + const value_type v{{"key1", value_type{{"key2", init}} }};\ + BOOST_TEST(init != opt); \ + BOOST_TEST(init == toml::find_or(v, "key1", "key2", opt));\ + } \ + /**/ + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_exact, value_type, test_value_types) +{ + TOML11_TEST_FIND_OR_EXACT(boolean, ( true), (false)) + TOML11_TEST_FIND_OR_EXACT(integer, ( 42), ( 54)) + TOML11_TEST_FIND_OR_EXACT(floating, ( 3.14), ( 2.71)) + TOML11_TEST_FIND_OR_EXACT(string, ("foo"), ("bar")) + TOML11_TEST_FIND_OR_EXACT(local_time, (12, 30, 45), (6, 0, 30)) + TOML11_TEST_FIND_OR_EXACT(local_date, (2019, toml::month_t::Apr, 1), + (1999, toml::month_t::Jan, 2)) + TOML11_TEST_FIND_OR_EXACT(local_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) + ) + TOML11_TEST_FIND_OR_EXACT(offset_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) + ) + { + const typename value_type::array_type init{1,2,3,4,5}; + const typename value_type::array_type opt {6,7,8,9,10}; + const value_type v{{"key", init}}; + BOOST_TEST(init != opt); + BOOST_TEST(init == toml::find_or(v, "key", opt)); + } + { + const typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; + const typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}}; + const value_type v{{"key", init}}; + BOOST_TEST(init != opt); + BOOST_TEST(init == toml::find_or(v, "key", opt)); + } +} +#undef TOML11_TEST_FIND_OR_EXACT + +#define TOML11_TEST_FIND_OR_MOVE(toml_type, init_expr, opt_expr) \ + { \ + using namespace test; \ + const toml::toml_type init init_expr ; \ + toml::toml_type opt opt_expr ; \ + value_type v{{"key1", value_type{{"key2", init}} }}; \ + BOOST_TEST(init != opt); \ + const auto moved = toml::find_or(std::move(v), "key1", "key2", std::move(opt));\ + BOOST_TEST(init == moved); \ + } \ + /**/ + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_move, value_type, test_value_types) +{ + TOML11_TEST_FIND_OR_MOVE(boolean, ( true), (false)) + TOML11_TEST_FIND_OR_MOVE(integer, ( 42), ( 54)) + TOML11_TEST_FIND_OR_MOVE(floating, ( 3.14), ( 2.71)) + TOML11_TEST_FIND_OR_MOVE(string, ("foo"), ("bar")) + TOML11_TEST_FIND_OR_MOVE(local_time, (12, 30, 45), (6, 0, 30)) + TOML11_TEST_FIND_OR_MOVE(local_date, (2019, toml::month_t::Apr, 1), + (1999, toml::month_t::Jan, 2)) + TOML11_TEST_FIND_OR_MOVE(local_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) + ) + TOML11_TEST_FIND_OR_MOVE(offset_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) + ) + { + typename value_type::array_type init{1,2,3,4,5}; + typename value_type::array_type opt {6,7,8,9,10}; + value_type v{{"key", init}}; + BOOST_TEST(init != opt); + const auto moved = toml::find_or(std::move(v), "key", std::move(opt)); + BOOST_TEST(init == moved); + } + { + typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; + typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}}; + value_type v{{"key", init}}; + BOOST_TEST(init != opt); + const auto moved = toml::find_or(std::move(v), "key", std::move(opt)); + BOOST_TEST(init == moved); + } +} +#undef TOML11_TEST_FIND_OR_MOVE + + +#define TOML11_TEST_FIND_OR_MODIFY(toml_type, init_expr, opt_expr)\ + { \ + using namespace test; \ + const toml::toml_type init init_expr ; \ + toml::toml_type opt1 opt_expr ; \ + toml::toml_type opt2 opt_expr ; \ + value_type v{{"key1", value_type{{"key2", init}} }}; \ + BOOST_TEST(init != opt1); \ + toml::find_or(v, "key1", "key2", opt2) = opt1; \ + BOOST_TEST(opt1 == toml::find(v, "key1", "key2"));\ + } \ + /**/ +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_modify, value_type, test_value_types) +{ + TOML11_TEST_FIND_OR_MODIFY(boolean, ( true), (false)) + TOML11_TEST_FIND_OR_MODIFY(integer, ( 42), ( 54)) + TOML11_TEST_FIND_OR_MODIFY(floating, ( 3.14), ( 2.71)) + TOML11_TEST_FIND_OR_MODIFY(string, ("foo"), ("bar")) + TOML11_TEST_FIND_OR_MODIFY(local_time, (12, 30, 45), (6, 0, 30)) + TOML11_TEST_FIND_OR_MODIFY(local_date, (2019, toml::month_t::Apr, 1), + (1999, toml::month_t::Jan, 2)) + TOML11_TEST_FIND_OR_MODIFY(local_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) + ) + TOML11_TEST_FIND_OR_MODIFY(offset_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) + ) + { + typename value_type::array_type init{1,2,3,4,5}; + typename value_type::array_type opt1{6,7,8,9,10}; + typename value_type::array_type opt2{6,7,8,9,10}; + BOOST_TEST(init != opt1); + value_type v{{"key", init}}; + toml::find_or(v, "key", opt2) = opt1; + BOOST_TEST(opt1 == toml::find(v, "key")); + } + { + typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; + typename value_type::table_type opt1{{"key1", 54}, {"key2", "bar"}}; + typename value_type::table_type opt2{{"key1", 54}, {"key2", "bar"}}; + value_type v{{"key", init}}; + BOOST_TEST(init != opt1); + toml::find_or(v, "key", opt2) = opt1; + BOOST_TEST(opt1 == toml::find(v, "key")); + } +} +#undef TOML11_TEST_FIND_OR_MODIFY + +#define TOML11_TEST_FIND_OR_FALLBACK(init_type, opt_type) \ + { \ + using namespace test; \ + value_type v1{{"key1", value_type{{"key3", "foo"}}}}; \ + BOOST_TEST(opt_type == toml::find_or(v1, "key1", "key2", opt_type));\ + value_type v2{{"key1", "foo"}}; \ + BOOST_TEST(opt_type == toml::find_or(v2, "key1", "key3", opt_type));\ + } \ + /**/ + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_fallback, value_type, test_value_types) +{ + const toml::boolean boolean (true); + const toml::integer integer (42); + const toml::floating floating (3.14); + const toml::string string ("foo"); + const toml::local_time local_time (12, 30, 45); + const toml::local_date local_date (2019, toml::month_t::Apr, 1); + const toml::local_datetime local_datetime ( + toml::local_date(2019, toml::month_t::Apr, 1), + toml::local_time(12, 30, 45)); + const toml::offset_datetime offset_datetime( + toml::local_date(2019, toml::month_t::Apr, 1), + toml::local_time(12, 30, 45), toml::time_offset( 9, 0)); + + using array_type = typename value_type::array_type; + using table_type = typename value_type::table_type; + const array_type array{1, 2, 3, 4, 5}; + const table_type table{{"key1", 42}, {"key2", "foo"}}; + + TOML11_TEST_FIND_OR_FALLBACK(boolean, integer ); + TOML11_TEST_FIND_OR_FALLBACK(boolean, floating ); + TOML11_TEST_FIND_OR_FALLBACK(boolean, string ); + TOML11_TEST_FIND_OR_FALLBACK(boolean, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(boolean, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(boolean, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(boolean, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(boolean, array ); + TOML11_TEST_FIND_OR_FALLBACK(boolean, table ); + + TOML11_TEST_FIND_OR_FALLBACK(integer, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(integer, floating ); + TOML11_TEST_FIND_OR_FALLBACK(integer, string ); + TOML11_TEST_FIND_OR_FALLBACK(integer, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(integer, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(integer, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(integer, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(integer, array ); + TOML11_TEST_FIND_OR_FALLBACK(integer, table ); + + TOML11_TEST_FIND_OR_FALLBACK(floating, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(floating, integer ); + TOML11_TEST_FIND_OR_FALLBACK(floating, string ); + TOML11_TEST_FIND_OR_FALLBACK(floating, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(floating, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(floating, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(floating, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(floating, array ); + TOML11_TEST_FIND_OR_FALLBACK(floating, table ); + + TOML11_TEST_FIND_OR_FALLBACK(string, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(string, integer ); + TOML11_TEST_FIND_OR_FALLBACK(string, floating ); + TOML11_TEST_FIND_OR_FALLBACK(string, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(string, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(string, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(string, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(string, array ); + TOML11_TEST_FIND_OR_FALLBACK(string, table ); + + TOML11_TEST_FIND_OR_FALLBACK(local_time, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(local_time, integer ); + TOML11_TEST_FIND_OR_FALLBACK(local_time, floating ); + TOML11_TEST_FIND_OR_FALLBACK(local_time, string ); + TOML11_TEST_FIND_OR_FALLBACK(local_time, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(local_time, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(local_time, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(local_time, array ); + TOML11_TEST_FIND_OR_FALLBACK(local_time, table ); + + TOML11_TEST_FIND_OR_FALLBACK(local_date, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(local_date, integer ); + TOML11_TEST_FIND_OR_FALLBACK(local_date, floating ); + TOML11_TEST_FIND_OR_FALLBACK(local_date, string ); + TOML11_TEST_FIND_OR_FALLBACK(local_date, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(local_date, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(local_date, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(local_date, array ); + TOML11_TEST_FIND_OR_FALLBACK(local_date, table ); + + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, integer ); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, floating ); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, string ); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, array ); + TOML11_TEST_FIND_OR_FALLBACK(local_datetime, table ); + + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, integer ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, floating ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, string ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, array ); + TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, table ); + + TOML11_TEST_FIND_OR_FALLBACK(array, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(array, integer ); + TOML11_TEST_FIND_OR_FALLBACK(array, floating ); + TOML11_TEST_FIND_OR_FALLBACK(array, string ); + TOML11_TEST_FIND_OR_FALLBACK(array, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(array, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(array, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(array, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(array, table ); + + TOML11_TEST_FIND_OR_FALLBACK(table, boolean ); + TOML11_TEST_FIND_OR_FALLBACK(table, integer ); + TOML11_TEST_FIND_OR_FALLBACK(table, floating ); + TOML11_TEST_FIND_OR_FALLBACK(table, string ); + TOML11_TEST_FIND_OR_FALLBACK(table, local_time ); + TOML11_TEST_FIND_OR_FALLBACK(table, local_date ); + TOML11_TEST_FIND_OR_FALLBACK(table, local_datetime ); + TOML11_TEST_FIND_OR_FALLBACK(table, offset_datetime); + TOML11_TEST_FIND_OR_FALLBACK(table, array ); +} +#undef TOML11_TEST_FIND_OR_FALLBACK + +struct move_only_type +{ + explicit move_only_type(const std::string& n): name_(n) {} + + void from_toml(const toml::value& v) + { + this->name_ = toml::find(v, "name"); + return; + } + + move_only_type(): name_("default"){} + ~move_only_type() = default; + move_only_type(move_only_type&&) = default; + move_only_type& operator=(move_only_type&&) = default; + move_only_type(const move_only_type&) = delete; + move_only_type& operator=(const move_only_type&) = delete; + + bool operator==(const move_only_type& other) const noexcept {return this->name_ == other.name_;} + bool operator!=(const move_only_type& other) const noexcept {return this->name_ != other.name_;} + bool operator< (const move_only_type& other) const noexcept {return this->name_ < other.name_;} + bool operator<=(const move_only_type& other) const noexcept {return this->name_ <= other.name_;} + bool operator> (const move_only_type& other) const noexcept {return this->name_ > other.name_;} + bool operator>=(const move_only_type& other) const noexcept {return this->name_ >= other.name_;} + + std::string name_; +}; + +std::ostream& operator<<(std::ostream& os, const move_only_type& mot) +{ + os << mot.name_; + return os; +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_move_only, value_type, test_value_types) +{ + const move_only_type ref("reference"); + move_only_type opt("optional"); + { + const value_type v{{"key1", value_type{{"key2", value_type{{"name", "reference"}} }} }}; + BOOST_TEST(ref == toml::find_or(v, "key1", "key2", std::move(opt))); + } +} diff --git a/external/toml11/tests/test_format_error.cpp b/external/toml11/tests/test_format_error.cpp new file mode 100644 index 0000000..c00f845 --- /dev/null +++ b/external/toml11/tests/test_format_error.cpp @@ -0,0 +1,72 @@ +#include + +#include "unit_test.hpp" + +#include + +// to check it successfully compiles. it does not check the formatted string. + +BOOST_AUTO_TEST_CASE(test_1_value) +{ + toml::value val(42); + + { + const std::string pretty_error = + toml::format_error("[error] test error", val, "this is a value"); + std::cout << pretty_error << std::endl; + } + + { + const std::string pretty_error = + toml::format_error("[error] test error", val, "this is a value", + {"this is a hint"}); + std::cout << pretty_error << std::endl; + } +} + +BOOST_AUTO_TEST_CASE(test_2_values) +{ + toml::value v1(42); + toml::value v2(3.14); + { + const std::string pretty_error = + toml::format_error("[error] test error with two values", + v1, "this is the answer", + v2, "this is the pi"); + std::cout << pretty_error << std::endl; + } + + { + const std::string pretty_error = + toml::format_error("[error] test error with two values", + v1, "this is the answer", + v2, "this is the pi", + {"hint"}); + std::cout << pretty_error << std::endl; + } +} + +BOOST_AUTO_TEST_CASE(test_3_values) +{ + toml::value v1(42); + toml::value v2(3.14); + toml::value v3("foo"); + { + const std::string pretty_error = + toml::format_error("[error] test error with two values", + v1, "this is the answer", + v2, "this is the pi", + v3, "this is a meta-syntactic variable"); + std::cout << pretty_error << std::endl; + } + + { + const std::string pretty_error = + toml::format_error("[error] test error with two values", + v1, "this is the answer", + v2, "this is the pi", + v3, "this is a meta-syntactic variable", + {"hint 1", "hint 2"}); + std::cout << pretty_error << std::endl; + } +} diff --git a/external/toml11/tests/test_get.cpp b/external/toml11/tests/test_get.cpp new file mode 100644 index 0000000..4a16e34 --- /dev/null +++ b/external/toml11/tests/test_get.cpp @@ -0,0 +1,505 @@ +#include + +#include "unit_test.hpp" + +#include +#include +#include +#include +#include +#include + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L +#include +#endif + +using test_value_types = std::tuple< + toml::basic_value, + toml::basic_value, + toml::basic_value, + toml::basic_value +>; + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types) +{ + { + value_type v(true); + BOOST_TEST(true == toml::get(v)); + + toml::get(v) = false; + BOOST_TEST(false == toml::get(v)); + + toml::boolean x = toml::get(std::move(v)); + BOOST_TEST(false == x); + } + { + value_type v(42); + BOOST_TEST(toml::integer(42) == toml::get(v)); + + toml::get(v) = 54; + BOOST_TEST(toml::integer(54) == toml::get(v)); + + toml::integer x = toml::get(std::move(v)); + BOOST_TEST(toml::integer(54) == x); + } + { + value_type v(3.14); + BOOST_TEST(toml::floating(3.14) == toml::get(v)); + + toml::get(v) = 2.71; + BOOST_TEST(toml::floating(2.71) == toml::get(v)); + + toml::floating x = toml::get(std::move(v)); + BOOST_TEST(toml::floating(2.71) == x); + } + { + value_type v("foo"); + BOOST_TEST(toml::string("foo", toml::string_t::basic) == + toml::get(v)); + + toml::get(v).str += "bar"; + BOOST_TEST(toml::string("foobar", toml::string_t::basic) == + toml::get(v)); + + toml::string x = toml::get(std::move(v)); + BOOST_TEST(toml::string("foobar") == x); + } + { + value_type v("foo", toml::string_t::literal); + BOOST_TEST(toml::string("foo", toml::string_t::literal) == + toml::get(v)); + + toml::get(v).str += "bar"; + BOOST_TEST(toml::string("foobar", toml::string_t::literal) == + toml::get(v)); + + toml::string x = toml::get(std::move(v)); + BOOST_TEST(toml::string("foobar", toml::string_t::literal) == x); + } + { + toml::local_date d(2018, toml::month_t::Apr, 22); + value_type v(d); + BOOST_TEST(d == toml::get(v)); + + toml::get(v).year = 2017; + d.year = 2017; + BOOST_TEST(d == toml::get(v)); + + toml::local_date x = toml::get(std::move(v)); + BOOST_TEST(d == x); + } + { + toml::local_time t(12, 30, 45); + value_type v(t); + BOOST_TEST(t == toml::get(v)); + + toml::get(v).hour = 9; + t.hour = 9; + BOOST_TEST(t == toml::get(v)); + + toml::local_time x = toml::get(std::move(v)); + BOOST_TEST(t == x); + } + { + toml::local_datetime dt(toml::local_date(2018, toml::month_t::Apr, 22), + toml::local_time(12, 30, 45)); + value_type v(dt); + BOOST_TEST(dt == toml::get(v)); + + toml::get(v).date.year = 2017; + dt.date.year = 2017; + BOOST_TEST(dt == toml::get(v)); + + toml::local_datetime x = toml::get(std::move(v)); + BOOST_TEST(dt == x); + } + { + toml::offset_datetime dt(toml::local_datetime( + toml::local_date(2018, toml::month_t::Apr, 22), + toml::local_time(12, 30, 45)), toml::time_offset(9, 0)); + value_type v(dt); + BOOST_TEST(dt == toml::get(v)); + + toml::get(v).date.year = 2017; + dt.date.year = 2017; + BOOST_TEST(dt == toml::get(v)); + + toml::offset_datetime x = toml::get(std::move(v)); + BOOST_TEST(dt == x); + } + { + using array_type = typename value_type::array_type; + array_type vec; + vec.push_back(value_type(42)); + vec.push_back(value_type(54)); + value_type v(vec); + BOOST_TEST(vec == toml::get(v)); + + toml::get(v).push_back(value_type(123)); + vec.push_back(value_type(123)); + BOOST_TEST(vec == toml::get(v)); + + array_type x = toml::get(std::move(v)); + BOOST_TEST(vec == x); + } + { + using table_type = typename value_type::table_type; + table_type tab; + tab["key1"] = value_type(42); + tab["key2"] = value_type(3.14); + value_type v(tab); + BOOST_TEST(tab == toml::get(v)); + + toml::get(v)["key3"] = value_type(123); + tab["key3"] = value_type(123); + BOOST_TEST(tab == toml::get(v)); + + table_type x = toml::get(std::move(v)); + BOOST_TEST(tab == x); + } + { + value_type v1(42); + BOOST_TEST(v1 == toml::get(v1)); + + value_type v2(54); + toml::get(v1) = v2; + BOOST_TEST(v2 == toml::get(v1)); + + value_type x = toml::get(std::move(v1)); + BOOST_TEST(v2 == x); + } +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_integer_type, value_type, test_value_types) +{ + { + value_type v(42); + BOOST_TEST(int(42) == toml::get(v)); + BOOST_TEST(short(42) == toml::get(v)); + BOOST_TEST(char(42) == toml::get(v)); + BOOST_TEST(unsigned(42) == toml::get(v)); + BOOST_TEST(long(42) == toml::get(v)); + BOOST_TEST(std::int64_t(42) == toml::get(v)); + BOOST_TEST(std::uint64_t(42) == toml::get(v)); + BOOST_TEST(std::int16_t(42) == toml::get(v)); + BOOST_TEST(std::uint16_t(42) == toml::get(v)); + + BOOST_TEST(std::uint16_t(42) == toml::get(std::move(v))); + } +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_floating_type, value_type, test_value_types) +{ + { + value_type v(3.14); + const double ref(3.14); + BOOST_TEST(static_cast(ref) == toml::get(v)); + BOOST_TEST( ref == toml::get(v)); + BOOST_TEST(static_cast(ref) == toml::get(v)); + BOOST_TEST(static_cast(ref) == toml::get(std::move(v))); + } +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_string_type, value_type, test_value_types) +{ + { + value_type v("foo", toml::string_t::basic); + BOOST_TEST("foo" == toml::get(v)); + toml::get(v) += "bar"; + BOOST_TEST("foobar" == toml::get(v)); + + const auto x = toml::get(std::move(v)); + BOOST_TEST("foobar" == x); + } + { + value_type v("foo", toml::string_t::literal); + BOOST_TEST("foo" == toml::get(v)); + toml::get(v) += "bar"; + BOOST_TEST("foobar" == toml::get(v)); + + const auto x = toml::get(std::move(v)); + BOOST_TEST("foobar" == x); + } + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L + { + value_type v("foo", toml::string_t::basic); + BOOST_TEST("foo" == toml::get(v)); + } + { + value_type v("foo", toml::string_t::literal); + BOOST_TEST("foo" == toml::get(v)); + } +#endif +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_array, value_type, test_value_types) +{ + { + const value_type v{42, 54, 69, 72}; + + const std::vector vec = toml::get>(v); + const std::list lst = toml::get>(v); + const std::deque deq = toml::get>(v); + + BOOST_TEST(42 == vec.at(0)); + BOOST_TEST(54 == vec.at(1)); + BOOST_TEST(69 == vec.at(2)); + BOOST_TEST(72 == vec.at(3)); + + std::list::const_iterator iter = lst.begin(); + BOOST_TEST(static_cast(42) == *(iter++)); + BOOST_TEST(static_cast(54) == *(iter++)); + BOOST_TEST(static_cast(69) == *(iter++)); + BOOST_TEST(static_cast(72) == *(iter++)); + + BOOST_TEST(static_cast(42) == deq.at(0)); + BOOST_TEST(static_cast(54) == deq.at(1)); + BOOST_TEST(static_cast(69) == deq.at(2)); + BOOST_TEST(static_cast(72) == deq.at(3)); + + std::array ary = toml::get>(v); + BOOST_TEST(42 == ary.at(0)); + BOOST_TEST(54 == ary.at(1)); + BOOST_TEST(69 == ary.at(2)); + BOOST_TEST(72 == ary.at(3)); + + std::tuple tpl = + toml::get>(v); + BOOST_TEST( 42 == std::get<0>(tpl)); + BOOST_TEST(static_cast(54) == std::get<1>(tpl)); + BOOST_TEST(static_cast(69) == std::get<2>(tpl)); + BOOST_TEST(static_cast(72) == std::get<3>(tpl)); + + const value_type p{3.14, 2.71}; + std::pair pr = toml::get >(p); + BOOST_TEST(3.14 == pr.first); + BOOST_TEST(2.71 == pr.second); + } + + { + value_type v{42, 54, 69, 72}; + const std::vector vec = toml::get>(std::move(v)); + BOOST_TEST(42 == vec.at(0)); + BOOST_TEST(54 == vec.at(1)); + BOOST_TEST(69 == vec.at(2)); + BOOST_TEST(72 == vec.at(3)); + } + { + value_type v{42, 54, 69, 72}; + const std::deque deq = toml::get>(std::move(v)); + BOOST_TEST(42 == deq.at(0)); + BOOST_TEST(54 == deq.at(1)); + BOOST_TEST(69 == deq.at(2)); + BOOST_TEST(72 == deq.at(3)); + } + { + value_type v{42, 54, 69, 72}; + const std::list lst = toml::get>(std::move(v)); + std::list::const_iterator iter = lst.begin(); + BOOST_TEST(42 == *(iter++)); + BOOST_TEST(54 == *(iter++)); + BOOST_TEST(69 == *(iter++)); + BOOST_TEST(72 == *(iter++)); + } + { + value_type v{42, 54, 69, 72}; + std::array ary = toml::get>(std::move(v)); + BOOST_TEST(42 == ary.at(0)); + BOOST_TEST(54 == ary.at(1)); + BOOST_TEST(69 == ary.at(2)); + BOOST_TEST(72 == ary.at(3)); + } + { + value_type v{42, 54, 69, 72}; + std::tuple tpl = + toml::get>(std::move(v)); + BOOST_TEST( 42 == std::get<0>(tpl)); + BOOST_TEST(static_cast(54) == std::get<1>(tpl)); + BOOST_TEST(static_cast(69) == std::get<2>(tpl)); + BOOST_TEST(static_cast(72) == std::get<3>(tpl)); + } +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_array_of_array, value_type, test_value_types) +{ + { + const value_type v1{42, 54, 69, 72}; + const value_type v2{"foo", "bar", "baz"}; + const value_type v{v1, v2}; + + std::pair, std::vector> p = + toml::get, std::vector>>(v); + + BOOST_TEST(p.first.size() == 4u); + BOOST_TEST(p.first.at(0) == 42); + BOOST_TEST(p.first.at(1) == 54); + BOOST_TEST(p.first.at(2) == 69); + BOOST_TEST(p.first.at(3) == 72); + + BOOST_TEST(p.second.size() == 3u); + BOOST_TEST(p.second.at(0) == "foo"); + BOOST_TEST(p.second.at(1) == "bar"); + BOOST_TEST(p.second.at(2) == "baz"); + + std::tuple, std::vector> t = + toml::get, std::vector>>(v); + + BOOST_TEST(std::get<0>(t).at(0) == 42); + BOOST_TEST(std::get<0>(t).at(1) == 54); + BOOST_TEST(std::get<0>(t).at(2) == 69); + BOOST_TEST(std::get<0>(t).at(3) == 72); + + BOOST_TEST(std::get<1>(t).at(0) == "foo"); + BOOST_TEST(std::get<1>(t).at(1) == "bar"); + BOOST_TEST(std::get<1>(t).at(2) == "baz"); + } + { + const value_type v1{42, 54, 69, 72}; + const value_type v2{"foo", "bar", "baz"}; + value_type v{v1, v2}; + + std::pair, std::vector> p = + toml::get, std::vector>>(std::move(v)); + + BOOST_TEST(p.first.size() == 4u); + BOOST_TEST(p.first.at(0) == 42); + BOOST_TEST(p.first.at(1) == 54); + BOOST_TEST(p.first.at(2) == 69); + BOOST_TEST(p.first.at(3) == 72); + + BOOST_TEST(p.second.size() == 3u); + BOOST_TEST(p.second.at(0) == "foo"); + BOOST_TEST(p.second.at(1) == "bar"); + BOOST_TEST(p.second.at(2) == "baz"); + } +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_table, value_type, test_value_types) +{ + { + const value_type v1{ + {"key1", 1}, + {"key2", 2}, + {"key3", 3}, + {"key4", 4} + }; + + const auto v = toml::get>(v1); + BOOST_TEST(v.at("key1") == 1); + BOOST_TEST(v.at("key2") == 2); + BOOST_TEST(v.at("key3") == 3); + BOOST_TEST(v.at("key4") == 4); + } + { + value_type v1{ + {"key1", 1}, + {"key2", 2}, + {"key3", 3}, + {"key4", 4} + }; + const auto v = toml::get>(std::move(v1)); + BOOST_TEST(v.at("key1") == 1); + BOOST_TEST(v.at("key2") == 2); + BOOST_TEST(v.at("key3") == 3); + BOOST_TEST(v.at("key4") == 4); + } + +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_local_date, value_type, test_value_types) +{ + value_type v1(toml::local_date{2018, toml::month_t::Apr, 1}); + const auto date = std::chrono::system_clock::to_time_t( + toml::get(v1)); + + std::tm t; + t.tm_year = 2018 - 1900; + t.tm_mon = 4 - 1; + t.tm_mday = 1; + t.tm_hour = 0; + t.tm_min = 0; + t.tm_sec = 0; + t.tm_isdst = -1; + const auto c = std::mktime(&t); + BOOST_TEST(c == date); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_local_time, value_type, test_value_types) +{ + value_type v1(toml::local_time{12, 30, 45}); + const auto time = toml::get(v1); + const bool result = time == std::chrono::hours(12) + + std::chrono::minutes(30) + + std::chrono::seconds(45); + BOOST_TEST(result); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_local_datetime, value_type, test_value_types) +{ + value_type v1(toml::local_datetime( + toml::local_date{2018, toml::month_t::Apr, 1}, + toml::local_time{12, 30, 45})); + + const auto date = std::chrono::system_clock::to_time_t( + toml::get(v1)); + std::tm t; + t.tm_year = 2018 - 1900; + t.tm_mon = 4 - 1; + t.tm_mday = 1; + t.tm_hour = 12; + t.tm_min = 30; + t.tm_sec = 45; + t.tm_isdst = -1; + const auto c = std::mktime(&t); + BOOST_TEST(c == date); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_offset_datetime, value_type, test_value_types) +{ + { + value_type v1(toml::offset_datetime( + toml::local_date{2018, toml::month_t::Apr, 1}, + toml::local_time{12, 30, 0}, + toml::time_offset{9, 0})); + // 2018-04-01T12:30:00+09:00 + // == 2018-04-01T03:30:00Z + + const auto date = toml::get(v1); + const auto timet = std::chrono::system_clock::to_time_t(date); + + // get time_t as gmtime (2018-04-01T03:30:00Z) + const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! + BOOST_TEST(tmp); + const auto tm = *tmp; + BOOST_TEST(tm.tm_year + 1900 == 2018); + BOOST_TEST(tm.tm_mon + 1 == 4); + BOOST_TEST(tm.tm_mday == 1); + BOOST_TEST(tm.tm_hour == 3); + BOOST_TEST(tm.tm_min == 30); + BOOST_TEST(tm.tm_sec == 0); + } + + { + value_type v1(toml::offset_datetime( + toml::local_date{2018, toml::month_t::Apr, 1}, + toml::local_time{12, 30, 0}, + toml::time_offset{-8, 0})); + // 2018-04-01T12:30:00-08:00 + // == 2018-04-01T20:30:00Z + + const auto date = toml::get(v1); + const auto timet = std::chrono::system_clock::to_time_t(date); + + // get time_t as gmtime (2018-04-01T03:30:00Z) + const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! + BOOST_TEST(tmp); + const auto tm = *tmp; + BOOST_TEST(tm.tm_year + 1900 == 2018); + BOOST_TEST(tm.tm_mon + 1 == 4); + BOOST_TEST(tm.tm_mday == 1); + BOOST_TEST(tm.tm_hour == 20); + BOOST_TEST(tm.tm_min == 30); + BOOST_TEST(tm.tm_sec == 0); + } +} diff --git a/external/toml11/tests/test_get_or.cpp b/external/toml11/tests/test_get_or.cpp new file mode 100644 index 0000000..9ecb36e --- /dev/null +++ b/external/toml11/tests/test_get_or.cpp @@ -0,0 +1,449 @@ +#include + +#include "unit_test.hpp" + +#include +#include +#include +#include +#include +#include + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L +#include +#endif + +using test_value_types = std::tuple< + toml::basic_value, + toml::basic_value, + toml::basic_value, + toml::basic_value +>; + +namespace test +{ +// to compare result values in BOOST_TEST(). +// +// BOOST_TEST outputs the expected and actual values. Thus it includes the +// output stream operator inside. To compile it, we need operator< +std::basic_ostream& +operator<<(std::basic_ostream& os, const std::vector& v) +{ + os << "[ "; + for(const auto& i : v) {os << i << ' ';} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const std::deque& v) +{ + os << "[ "; + for(const auto& i : v) {os << i << ' ';} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const std::list& v) +{ + os << "[ "; + for(const auto& i : v) {os << i << ' ';} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + const std::map& v) +{ + os << "[ "; + for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + const std::unordered_map& v) +{ + os << "[ "; + for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";} + os << ']'; + return os; +} +} // test + +#define TOML11_TEST_GET_OR_EXACT(toml_type, init_expr, opt_expr)\ + { \ + using namespace test; \ + const toml::toml_type init init_expr ; \ + const toml::toml_type opt opt_expr ; \ + const value_type v(init); \ + BOOST_TEST(init != opt); \ + BOOST_TEST(init == toml::get_or(v, opt)); \ + } \ + /**/ + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_or_exact, value_type, test_value_types) +{ + TOML11_TEST_GET_OR_EXACT(boolean, ( true), (false)) + TOML11_TEST_GET_OR_EXACT(integer, ( 42), ( 54)) + TOML11_TEST_GET_OR_EXACT(floating, ( 3.14), ( 2.71)) + TOML11_TEST_GET_OR_EXACT(string, ("foo"), ("bar")) + TOML11_TEST_GET_OR_EXACT(local_time, (12, 30, 45), (6, 0, 30)) + TOML11_TEST_GET_OR_EXACT(local_date, (2019, toml::month_t::Apr, 1), + (1999, toml::month_t::Jan, 2)) + TOML11_TEST_GET_OR_EXACT(local_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) + ) + TOML11_TEST_GET_OR_EXACT(offset_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) + ) + { + const typename value_type::array_type init{1,2,3,4,5}; + const typename value_type::array_type opt {6,7,8,9,10}; + const value_type v(init); + BOOST_TEST(init != opt); + BOOST_TEST(init == toml::get_or(v, opt)); + } + { + const typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; + const typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}}; + const value_type v(init); + BOOST_TEST(init != opt); + BOOST_TEST(init == toml::get_or(v, opt)); + } +} +#undef TOML11_TEST_GET_OR_EXACT + +#define TOML11_TEST_GET_OR_MOVE_EXACT(toml_type, init_expr, opt_expr)\ + { \ + using namespace test; \ + const toml::toml_type init init_expr ; \ + toml::toml_type opt opt_expr ; \ + value_type v(init); \ + BOOST_TEST(init != opt); \ + const auto opt_ = toml::get_or(std::move(v), std::move(opt));\ + BOOST_TEST(init == opt_); \ + } \ + /**/ + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_or_move, value_type, test_value_types) +{ + TOML11_TEST_GET_OR_MOVE_EXACT(boolean, ( true), (false)) + TOML11_TEST_GET_OR_MOVE_EXACT(integer, ( 42), ( 54)) + TOML11_TEST_GET_OR_MOVE_EXACT(floating, ( 3.14), ( 2.71)) + TOML11_TEST_GET_OR_MOVE_EXACT(string, ("foo"), ("bar")) + TOML11_TEST_GET_OR_MOVE_EXACT(local_time, (12, 30, 45), (6, 0, 30)) + TOML11_TEST_GET_OR_MOVE_EXACT(local_date, (2019, toml::month_t::Apr, 1), + (1999, toml::month_t::Jan, 2)) + TOML11_TEST_GET_OR_MOVE_EXACT(local_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) + ) + TOML11_TEST_GET_OR_MOVE_EXACT(offset_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) + ) + { + const typename value_type::array_type init{1,2,3,4,5}; + typename value_type::array_type opt {6,7,8,9,10}; + value_type v(init); + BOOST_TEST(init != opt); + const auto opt_ = toml::get_or(std::move(v), std::move(opt)); + BOOST_TEST(init == opt_); + } + { + const typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; + typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}}; + value_type v(init); + BOOST_TEST(init != opt); + const auto opt_ = toml::get_or(std::move(v), std::move(opt)); + BOOST_TEST(init == opt_); + } +} +#undef TOML11_TEST_GET_OR_MOVE_EXACT + + +#define TOML11_TEST_GET_OR_MODIFY(toml_type, init_expr, opt_expr)\ + { \ + using namespace test; \ + const toml::toml_type init init_expr ; \ + toml::toml_type opt1 opt_expr ; \ + toml::toml_type opt2 opt_expr ; \ + value_type v(init); \ + BOOST_TEST(init != opt1); \ + toml::get_or(v, opt2) = opt1; \ + BOOST_TEST(opt1 == toml::get(v)); \ + } \ + /**/ +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_or_modify, value_type, test_value_types) +{ + TOML11_TEST_GET_OR_MODIFY(boolean, ( true), (false)) + TOML11_TEST_GET_OR_MODIFY(integer, ( 42), ( 54)) + TOML11_TEST_GET_OR_MODIFY(floating, ( 3.14), ( 2.71)) + TOML11_TEST_GET_OR_MODIFY(string, ("foo"), ("bar")) + TOML11_TEST_GET_OR_MODIFY(local_time, (12, 30, 45), (6, 0, 30)) + TOML11_TEST_GET_OR_MODIFY(local_date, (2019, toml::month_t::Apr, 1), + (1999, toml::month_t::Jan, 2)) + TOML11_TEST_GET_OR_MODIFY(local_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) + ) + TOML11_TEST_GET_OR_MODIFY(offset_datetime, + (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), + (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) + ) + { + typename value_type::array_type init{1,2,3,4,5}; + typename value_type::array_type opt1{6,7,8,9,10}; + typename value_type::array_type opt2{6,7,8,9,10}; + BOOST_TEST(init != opt1); + value_type v(init); + toml::get_or(v, opt2) = opt1; + BOOST_TEST(opt1 == toml::get(v)); + } + { + typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; + typename value_type::table_type opt1{{"key1", 54}, {"key2", "bar"}}; + typename value_type::table_type opt2{{"key1", 54}, {"key2", "bar"}}; + value_type v(init); + BOOST_TEST(init != opt1); + toml::get_or(v, opt2) = opt1; + BOOST_TEST(opt1 == toml::get(v)); + } +} +#undef TOML11_TEST_GET_OR_MODIFY + +#define TOML11_TEST_GET_OR_FALLBACK(init_type, opt_type) \ + { \ + using namespace test; \ + value_type v(init_type); \ + BOOST_TEST(opt_type == toml::get_or(v, opt_type));\ + } \ + /**/ + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_or_fallback, value_type, test_value_types) +{ + const toml::boolean boolean (true); + const toml::integer integer (42); + const toml::floating floating (3.14); + const toml::string string ("foo"); + const toml::local_time local_time (12, 30, 45); + const toml::local_date local_date (2019, toml::month_t::Apr, 1); + const toml::local_datetime local_datetime ( + toml::local_date(2019, toml::month_t::Apr, 1), + toml::local_time(12, 30, 45)); + const toml::offset_datetime offset_datetime( + toml::local_date(2019, toml::month_t::Apr, 1), + toml::local_time(12, 30, 45), toml::time_offset( 9, 0)); + + using array_type = typename value_type::array_type; + using table_type = typename value_type::table_type; + const array_type array{1, 2, 3, 4, 5}; + const table_type table{{"key1", 42}, {"key2", "foo"}}; + + TOML11_TEST_GET_OR_FALLBACK(boolean, integer ); + TOML11_TEST_GET_OR_FALLBACK(boolean, floating ); + TOML11_TEST_GET_OR_FALLBACK(boolean, string ); + TOML11_TEST_GET_OR_FALLBACK(boolean, local_time ); + TOML11_TEST_GET_OR_FALLBACK(boolean, local_date ); + TOML11_TEST_GET_OR_FALLBACK(boolean, local_datetime ); + TOML11_TEST_GET_OR_FALLBACK(boolean, offset_datetime); + TOML11_TEST_GET_OR_FALLBACK(boolean, array ); + TOML11_TEST_GET_OR_FALLBACK(boolean, table ); + + TOML11_TEST_GET_OR_FALLBACK(integer, boolean ); + TOML11_TEST_GET_OR_FALLBACK(integer, floating ); + TOML11_TEST_GET_OR_FALLBACK(integer, string ); + TOML11_TEST_GET_OR_FALLBACK(integer, local_time ); + TOML11_TEST_GET_OR_FALLBACK(integer, local_date ); + TOML11_TEST_GET_OR_FALLBACK(integer, local_datetime ); + TOML11_TEST_GET_OR_FALLBACK(integer, offset_datetime); + TOML11_TEST_GET_OR_FALLBACK(integer, array ); + TOML11_TEST_GET_OR_FALLBACK(integer, table ); + + TOML11_TEST_GET_OR_FALLBACK(floating, boolean ); + TOML11_TEST_GET_OR_FALLBACK(floating, integer ); + TOML11_TEST_GET_OR_FALLBACK(floating, string ); + TOML11_TEST_GET_OR_FALLBACK(floating, local_time ); + TOML11_TEST_GET_OR_FALLBACK(floating, local_date ); + TOML11_TEST_GET_OR_FALLBACK(floating, local_datetime ); + TOML11_TEST_GET_OR_FALLBACK(floating, offset_datetime); + TOML11_TEST_GET_OR_FALLBACK(floating, array ); + TOML11_TEST_GET_OR_FALLBACK(floating, table ); + + TOML11_TEST_GET_OR_FALLBACK(string, boolean ); + TOML11_TEST_GET_OR_FALLBACK(string, integer ); + TOML11_TEST_GET_OR_FALLBACK(string, floating ); + TOML11_TEST_GET_OR_FALLBACK(string, local_time ); + TOML11_TEST_GET_OR_FALLBACK(string, local_date ); + TOML11_TEST_GET_OR_FALLBACK(string, local_datetime ); + TOML11_TEST_GET_OR_FALLBACK(string, offset_datetime); + TOML11_TEST_GET_OR_FALLBACK(string, array ); + TOML11_TEST_GET_OR_FALLBACK(string, table ); + + TOML11_TEST_GET_OR_FALLBACK(local_time, boolean ); + TOML11_TEST_GET_OR_FALLBACK(local_time, integer ); + TOML11_TEST_GET_OR_FALLBACK(local_time, floating ); + TOML11_TEST_GET_OR_FALLBACK(local_time, string ); + TOML11_TEST_GET_OR_FALLBACK(local_time, local_date ); + TOML11_TEST_GET_OR_FALLBACK(local_time, local_datetime ); + TOML11_TEST_GET_OR_FALLBACK(local_time, offset_datetime); + TOML11_TEST_GET_OR_FALLBACK(local_time, array ); + TOML11_TEST_GET_OR_FALLBACK(local_time, table ); + + TOML11_TEST_GET_OR_FALLBACK(local_date, boolean ); + TOML11_TEST_GET_OR_FALLBACK(local_date, integer ); + TOML11_TEST_GET_OR_FALLBACK(local_date, floating ); + TOML11_TEST_GET_OR_FALLBACK(local_date, string ); + TOML11_TEST_GET_OR_FALLBACK(local_date, local_time ); + TOML11_TEST_GET_OR_FALLBACK(local_date, local_datetime ); + TOML11_TEST_GET_OR_FALLBACK(local_date, offset_datetime); + TOML11_TEST_GET_OR_FALLBACK(local_date, array ); + TOML11_TEST_GET_OR_FALLBACK(local_date, table ); + + TOML11_TEST_GET_OR_FALLBACK(local_datetime, boolean ); + TOML11_TEST_GET_OR_FALLBACK(local_datetime, integer ); + TOML11_TEST_GET_OR_FALLBACK(local_datetime, floating ); + TOML11_TEST_GET_OR_FALLBACK(local_datetime, string ); + TOML11_TEST_GET_OR_FALLBACK(local_datetime, local_time ); + TOML11_TEST_GET_OR_FALLBACK(local_datetime, local_date ); + TOML11_TEST_GET_OR_FALLBACK(local_datetime, offset_datetime); + TOML11_TEST_GET_OR_FALLBACK(local_datetime, array ); + TOML11_TEST_GET_OR_FALLBACK(local_datetime, table ); + + TOML11_TEST_GET_OR_FALLBACK(offset_datetime, boolean ); + TOML11_TEST_GET_OR_FALLBACK(offset_datetime, integer ); + TOML11_TEST_GET_OR_FALLBACK(offset_datetime, floating ); + TOML11_TEST_GET_OR_FALLBACK(offset_datetime, string ); + TOML11_TEST_GET_OR_FALLBACK(offset_datetime, local_time ); + TOML11_TEST_GET_OR_FALLBACK(offset_datetime, local_date ); + TOML11_TEST_GET_OR_FALLBACK(offset_datetime, local_datetime ); + TOML11_TEST_GET_OR_FALLBACK(offset_datetime, array ); + TOML11_TEST_GET_OR_FALLBACK(offset_datetime, table ); + + TOML11_TEST_GET_OR_FALLBACK(array, boolean ); + TOML11_TEST_GET_OR_FALLBACK(array, integer ); + TOML11_TEST_GET_OR_FALLBACK(array, floating ); + TOML11_TEST_GET_OR_FALLBACK(array, string ); + TOML11_TEST_GET_OR_FALLBACK(array, local_time ); + TOML11_TEST_GET_OR_FALLBACK(array, local_date ); + TOML11_TEST_GET_OR_FALLBACK(array, local_datetime ); + TOML11_TEST_GET_OR_FALLBACK(array, offset_datetime); + TOML11_TEST_GET_OR_FALLBACK(array, table ); + + TOML11_TEST_GET_OR_FALLBACK(table, boolean ); + TOML11_TEST_GET_OR_FALLBACK(table, integer ); + TOML11_TEST_GET_OR_FALLBACK(table, floating ); + TOML11_TEST_GET_OR_FALLBACK(table, string ); + TOML11_TEST_GET_OR_FALLBACK(table, local_time ); + TOML11_TEST_GET_OR_FALLBACK(table, local_date ); + TOML11_TEST_GET_OR_FALLBACK(table, local_datetime ); + TOML11_TEST_GET_OR_FALLBACK(table, offset_datetime); + TOML11_TEST_GET_OR_FALLBACK(table, array ); +} +#undef TOML11_TEST_GET_OR_FALLBACK + +BOOST_AUTO_TEST_CASE(test_get_or_integer) +{ + { + toml::value v1(42); + toml::value v2(3.14); + BOOST_TEST(42u == toml::get_or(v1, 0u)); + BOOST_TEST(0u == toml::get_or(v2, 0u)); + } + { + toml::value v1(42); + toml::value v2(3.14); + BOOST_TEST(42u == toml::get_or(std::move(v1), 0u)); + BOOST_TEST(0u == toml::get_or(std::move(v2), 0u)); + } + +} + +BOOST_AUTO_TEST_CASE(test_get_or_floating) +{ + { + toml::value v1(42); + toml::value v2(3.14); + BOOST_TEST(2.71f == toml::get_or(v1, 2.71f)); + BOOST_TEST(static_cast(v2.as_floating()) == toml::get_or(v2, 2.71f)); + } + { + toml::value v1(42); + toml::value v2(3.14); + BOOST_TEST(2.71f == toml::get_or(std::move(v1), 2.71f)); + BOOST_TEST(static_cast(3.14) == toml::get_or(std::move(v2), 2.71f)); + } +} + +BOOST_AUTO_TEST_CASE(test_get_or_string) +{ + { + toml::value v1("foobar"); + toml::value v2(42); + + std::string s1("bazqux"); + const std::string s2("bazqux"); + + BOOST_TEST("foobar" == toml::get_or(v1, s1)); + BOOST_TEST("bazqux" == toml::get_or(v2, s1)); + + std::string& v1r = toml::get_or(v1, s1); + std::string& s1r = toml::get_or(v2, s1); + + BOOST_TEST("foobar" == v1r); + BOOST_TEST("bazqux" == s1r); + + BOOST_TEST("foobar" == toml::get_or(v1, s2)); + BOOST_TEST("bazqux" == toml::get_or(v2, s2)); + + BOOST_TEST("foobar" == toml::get_or(v1, std::move(s1))); + BOOST_TEST("bazqux" == toml::get_or(v2, std::move(s1))); + } + { + toml::value v1("foobar"); + toml::value v2(42); + + std::string s1("bazqux"); + const std::string s2("bazqux"); + + BOOST_TEST("foobar" == toml::get_or(std::move(v1), s1)); + BOOST_TEST("bazqux" == toml::get_or(std::move(v2), s1)); + } + { + toml::value v1("foobar"); + toml::value v2(42); + + BOOST_TEST("foobar" == toml::get_or(v1, "bazqux")); + BOOST_TEST("bazqux" == toml::get_or(v2, "bazqux")); + + const char* lit = "bazqux"; + BOOST_TEST("foobar" == toml::get_or(v1, lit)); + BOOST_TEST("bazqux" == toml::get_or(v2, lit)); + } + { + toml::value v1("foobar"); + toml::value v2(42); + + BOOST_TEST("foobar" == toml::get_or(std::move(v1), "bazqux")); + BOOST_TEST("bazqux" == toml::get_or(std::move(v2), "bazqux")); + } + { + toml::value v1("foobar"); + toml::value v2(42); + + const char* lit = "bazqux"; + BOOST_TEST("foobar" == toml::get_or(v1, lit)); + BOOST_TEST("bazqux" == toml::get_or(v2, lit)); + } + +} diff --git a/external/toml11/tests/test_lex_aux.hpp b/external/toml11/tests/test_lex_aux.hpp new file mode 100644 index 0000000..77f2a9b --- /dev/null +++ b/external/toml11/tests/test_lex_aux.hpp @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include + +#define TOML11_TEST_LEX_ACCEPT(lxr, tkn, expct) \ +do { \ + const std::string token (tkn); \ + const std::string expected(expct); \ + toml::detail::location loc("test", token); \ + const auto result = lxr::invoke(loc); \ + BOOST_TEST(result.is_ok()); \ + if(result.is_ok()){ \ + const auto region = result.unwrap(); \ + BOOST_TEST(region.str() == expected); \ + BOOST_TEST(region.str().size() == expected.size()); \ + BOOST_TEST(static_cast(std::distance( \ + loc.begin(), loc.iter())) == region.size()); \ + } else { \ + std::cerr << "lexer failed with input `"; \ + std::cerr << token << "`. expected `" << expected << "`\n"; \ + std::cerr << "reason: " << result.unwrap_err() << '\n'; \ + } \ +} while(false); \ +/**/ + +#define TOML11_TEST_LEX_REJECT(lxr, tkn) \ +do { \ + const std::string token (tkn); \ + toml::detail::location loc("test", token); \ + const auto result = lxr::invoke(loc); \ + BOOST_TEST(result.is_err()); \ + const bool loc_same = (loc.begin() == loc.iter()); \ + BOOST_TEST(loc_same); \ +} while(false); /**/ diff --git a/external/toml11/tests/test_lex_boolean.cpp b/external/toml11/tests/test_lex_boolean.cpp new file mode 100644 index 0000000..deecffe --- /dev/null +++ b/external/toml11/tests/test_lex_boolean.cpp @@ -0,0 +1,23 @@ +#include + +#include "unit_test.hpp" +#include "test_lex_aux.hpp" + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_correct) +{ + TOML11_TEST_LEX_ACCEPT(lex_boolean, "true", "true"); + TOML11_TEST_LEX_ACCEPT(lex_boolean, "false", "false"); + TOML11_TEST_LEX_ACCEPT(lex_boolean, "true # trailing", "true"); + TOML11_TEST_LEX_ACCEPT(lex_boolean, "false # trailing", "false"); +} + +BOOST_AUTO_TEST_CASE(test_invalid) +{ + TOML11_TEST_LEX_REJECT(lex_boolean, "TRUE"); + TOML11_TEST_LEX_REJECT(lex_boolean, "FALSE"); + TOML11_TEST_LEX_REJECT(lex_boolean, "True"); + TOML11_TEST_LEX_REJECT(lex_boolean, "False"); +} diff --git a/external/toml11/tests/test_lex_datetime.cpp b/external/toml11/tests/test_lex_datetime.cpp new file mode 100644 index 0000000..8e33d38 --- /dev/null +++ b/external/toml11/tests/test_lex_datetime.cpp @@ -0,0 +1,57 @@ +#include + +#include "unit_test.hpp" +#include "test_lex_aux.hpp" + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_offset_datetime) +{ + TOML11_TEST_LEX_ACCEPT(lex_offset_date_time, + "1979-05-27T07:32:00Z", + "1979-05-27T07:32:00Z"); + TOML11_TEST_LEX_ACCEPT(lex_offset_date_time, + "1979-05-27T07:32:00-07:00", + "1979-05-27T07:32:00-07:00"); + TOML11_TEST_LEX_ACCEPT(lex_offset_date_time, + "1979-05-27T07:32:00.999999-07:00", + "1979-05-27T07:32:00.999999-07:00"); + + TOML11_TEST_LEX_ACCEPT(lex_offset_date_time, + "1979-05-27 07:32:00Z", + "1979-05-27 07:32:00Z"); + TOML11_TEST_LEX_ACCEPT(lex_offset_date_time, + "1979-05-27 07:32:00-07:00", + "1979-05-27 07:32:00-07:00"); + TOML11_TEST_LEX_ACCEPT(lex_offset_date_time, + "1979-05-27 07:32:00.999999-07:00", + "1979-05-27 07:32:00.999999-07:00"); +} + +BOOST_AUTO_TEST_CASE(test_local_datetime) +{ + TOML11_TEST_LEX_ACCEPT(lex_local_date_time, + "1979-05-27T07:32:00", + "1979-05-27T07:32:00"); + TOML11_TEST_LEX_ACCEPT(lex_local_date_time, + "1979-05-27T07:32:00.999999", + "1979-05-27T07:32:00.999999"); + + TOML11_TEST_LEX_ACCEPT(lex_local_date_time, + "1979-05-27 07:32:00", + "1979-05-27 07:32:00"); + TOML11_TEST_LEX_ACCEPT(lex_local_date_time, + "1979-05-27 07:32:00.999999", + "1979-05-27 07:32:00.999999"); +} + +BOOST_AUTO_TEST_CASE(test_local_date) +{ + TOML11_TEST_LEX_ACCEPT(lex_local_date, "1979-05-27", "1979-05-27"); +} +BOOST_AUTO_TEST_CASE(test_local_time) +{ + TOML11_TEST_LEX_ACCEPT(lex_local_time, "07:32:00", "07:32:00"); + TOML11_TEST_LEX_ACCEPT(lex_local_time, "07:32:00.999999", "07:32:00.999999"); +} diff --git a/external/toml11/tests/test_lex_floating.cpp b/external/toml11/tests/test_lex_floating.cpp new file mode 100644 index 0000000..8c9cd20 --- /dev/null +++ b/external/toml11/tests/test_lex_floating.cpp @@ -0,0 +1,107 @@ +#include + +#include "unit_test.hpp" +#include "test_lex_aux.hpp" + +#include + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_fractional_valid) +{ + TOML11_TEST_LEX_ACCEPT(lex_float, "1.0", "1.0" ); + TOML11_TEST_LEX_ACCEPT(lex_float, "0.1", "0.1" ); + TOML11_TEST_LEX_ACCEPT(lex_float, "0.001", "0.001" ); + TOML11_TEST_LEX_ACCEPT(lex_float, "0.100", "0.100" ); + TOML11_TEST_LEX_ACCEPT(lex_float, "+3.14", "+3.14" ); + TOML11_TEST_LEX_ACCEPT(lex_float, "-3.14", "-3.14" ); + TOML11_TEST_LEX_ACCEPT(lex_float, "3.1415_9265_3589", "3.1415_9265_3589" ); + TOML11_TEST_LEX_ACCEPT(lex_float, "+3.1415_9265_3589", "+3.1415_9265_3589"); + TOML11_TEST_LEX_ACCEPT(lex_float, "-3.1415_9265_3589", "-3.1415_9265_3589"); + TOML11_TEST_LEX_ACCEPT(lex_float, "123_456.789", "123_456.789" ); + TOML11_TEST_LEX_ACCEPT(lex_float, "+123_456.789", "+123_456.789" ); + TOML11_TEST_LEX_ACCEPT(lex_float, "-123_456.789", "-123_456.789" ); +} + +BOOST_AUTO_TEST_CASE(test_fractional_invalid) +{ + TOML11_TEST_LEX_REJECT(lex_float, "0."); + TOML11_TEST_LEX_REJECT(lex_float, ".0"); + TOML11_TEST_LEX_REJECT(lex_float, "01.0"); + TOML11_TEST_LEX_REJECT(lex_float, "3,14"); + TOML11_TEST_LEX_REJECT(lex_float, "+-1.0"); + TOML11_TEST_LEX_REJECT(lex_float, "1._0"); +} + +BOOST_AUTO_TEST_CASE(test_exponential_valid) +{ + TOML11_TEST_LEX_ACCEPT(lex_float, "1e10", "1e10"); + TOML11_TEST_LEX_ACCEPT(lex_float, "1e+10", "1e+10"); + TOML11_TEST_LEX_ACCEPT(lex_float, "1e-10", "1e-10"); + TOML11_TEST_LEX_ACCEPT(lex_float, "+1e10", "+1e10"); + TOML11_TEST_LEX_ACCEPT(lex_float, "+1e+10", "+1e+10"); + TOML11_TEST_LEX_ACCEPT(lex_float, "+1e-10", "+1e-10"); + TOML11_TEST_LEX_ACCEPT(lex_float, "-1e10", "-1e10"); + TOML11_TEST_LEX_ACCEPT(lex_float, "-1e+10", "-1e+10"); + TOML11_TEST_LEX_ACCEPT(lex_float, "-1e-10", "-1e-10"); + TOML11_TEST_LEX_ACCEPT(lex_float, "123e-10", "123e-10"); + TOML11_TEST_LEX_ACCEPT(lex_float, "1E10", "1E10"); + TOML11_TEST_LEX_ACCEPT(lex_float, "1E+10", "1E+10"); + TOML11_TEST_LEX_ACCEPT(lex_float, "1E-10", "1E-10"); + TOML11_TEST_LEX_ACCEPT(lex_float, "123E-10", "123E-10"); + TOML11_TEST_LEX_ACCEPT(lex_float, "1_2_3E-10", "1_2_3E-10"); + TOML11_TEST_LEX_ACCEPT(lex_float, "1_2_3E-1_0", "1_2_3E-1_0"); + +#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES + BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part"); + // toml-lang/toml master permits leading 0s in exp part (unreleased) + TOML11_TEST_LEX_ACCEPT(lex_float, "1_2_3E-01", "1_2_3E-01"); + TOML11_TEST_LEX_ACCEPT(lex_float, "1_2_3E-0_1", "1_2_3E-0_1"); +#endif +} + +BOOST_AUTO_TEST_CASE(test_exponential_invalid) +{ + // accept partially + TOML11_TEST_LEX_ACCEPT(lex_float, "1e1E0", "1e1"); + TOML11_TEST_LEX_ACCEPT(lex_float, "1E1e0", "1E1"); +} + +BOOST_AUTO_TEST_CASE(test_both_valid) +{ + TOML11_TEST_LEX_ACCEPT(lex_float, "6.02e23", "6.02e23"); + TOML11_TEST_LEX_ACCEPT(lex_float, "6.02e+23", "6.02e+23"); + TOML11_TEST_LEX_ACCEPT(lex_float, "1.112_650_06e-17", "1.112_650_06e-17"); + +#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES + BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part"); + // toml-lang/toml master permits leading 0s in exp part (unreleased) + TOML11_TEST_LEX_ACCEPT(lex_float, "1.0e-07", "1.0e-07"); +#endif +} + +BOOST_AUTO_TEST_CASE(test_both_invalid) +{ + TOML11_TEST_LEX_REJECT(lex_float, "01e1.0"); + // accept partially + TOML11_TEST_LEX_ACCEPT(lex_float, "1e1.0", "1e1"); + +#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES + BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part"); + // toml-lang/toml master permits leading 0s in exp part (unreleased) + TOML11_TEST_LEX_ACCEPT(lex_float, "1.0e_01", "1.0"); + TOML11_TEST_LEX_ACCEPT(lex_float, "1.0e0__1", "1.0e0"); +#endif +} + +BOOST_AUTO_TEST_CASE(test_special_floating_point) +{ + TOML11_TEST_LEX_ACCEPT(lex_float, "inf", "inf"); + TOML11_TEST_LEX_ACCEPT(lex_float, "+inf", "+inf"); + TOML11_TEST_LEX_ACCEPT(lex_float, "-inf", "-inf"); + + TOML11_TEST_LEX_ACCEPT(lex_float, "nan", "nan"); + TOML11_TEST_LEX_ACCEPT(lex_float, "+nan", "+nan"); + TOML11_TEST_LEX_ACCEPT(lex_float, "-nan", "-nan"); +} diff --git a/external/toml11/tests/test_lex_integer.cpp b/external/toml11/tests/test_lex_integer.cpp new file mode 100644 index 0000000..50b9178 --- /dev/null +++ b/external/toml11/tests/test_lex_integer.cpp @@ -0,0 +1,101 @@ +#include + +#include "unit_test.hpp" +#include "test_lex_aux.hpp" + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_decimal_correct) +{ + TOML11_TEST_LEX_ACCEPT(lex_integer, "1234", "1234" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "+1234", "+1234" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "-1234", "-1234" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0", "0" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "1_2_3_4", "1_2_3_4" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "+1_2_3_4", "+1_2_3_4" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "-1_2_3_4", "-1_2_3_4" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "123_456_789", "123_456_789"); +} + +BOOST_AUTO_TEST_CASE(test_decimal_invalid) +{ + TOML11_TEST_LEX_ACCEPT(lex_integer, "123+45", "123"); + TOML11_TEST_LEX_ACCEPT(lex_integer, "123-45", "123"); + TOML11_TEST_LEX_ACCEPT(lex_integer, "01234", "0"); + TOML11_TEST_LEX_ACCEPT(lex_integer, "123__45", "123"); + + TOML11_TEST_LEX_REJECT(lex_integer, "_1234"); +} + +BOOST_AUTO_TEST_CASE(test_hex_correct) +{ + TOML11_TEST_LEX_ACCEPT(lex_integer, "0xDEADBEEF", "0xDEADBEEF" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0xdeadbeef", "0xdeadbeef" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0xDEADbeef", "0xDEADbeef" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0xDEAD_BEEF", "0xDEAD_BEEF"); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0xdead_beef", "0xdead_beef"); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0xdead_BEEF", "0xdead_BEEF"); + + TOML11_TEST_LEX_ACCEPT(lex_integer, "0xFF", "0xFF" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0x00FF", "0x00FF" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0x0000FF", "0x0000FF"); +} + +BOOST_AUTO_TEST_CASE(test_hex_invalid) +{ + TOML11_TEST_LEX_ACCEPT(lex_integer, "0xAPPLE", "0xA"); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0xDEAD+BEEF", "0xDEAD"); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0xDEAD__BEEF", "0xDEAD"); + + TOML11_TEST_LEX_REJECT(lex_hex_int, "0x_DEADBEEF"); + TOML11_TEST_LEX_REJECT(lex_hex_int, "0x+DEADBEEF"); + TOML11_TEST_LEX_REJECT(lex_hex_int, "-0xFF" ); + TOML11_TEST_LEX_REJECT(lex_hex_int, "-0x00FF" ); + + TOML11_TEST_LEX_ACCEPT(lex_integer, "0x_DEADBEEF", "0" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0x+DEADBEEF", "0" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "-0xFF" , "-0" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "-0x00FF" , "-0" ); +} + +BOOST_AUTO_TEST_CASE(test_oct_correct) +{ + TOML11_TEST_LEX_ACCEPT(lex_integer, "0o777", "0o777" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0o7_7_7", "0o7_7_7"); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0o007", "0o007" ); + +} + +BOOST_AUTO_TEST_CASE(test_oct_invalid) +{ + TOML11_TEST_LEX_ACCEPT(lex_integer, "0o77+7", "0o77"); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0o1__0", "0o1"); + + TOML11_TEST_LEX_REJECT(lex_oct_int, "0o800" ); + TOML11_TEST_LEX_REJECT(lex_oct_int, "-0o777"); + TOML11_TEST_LEX_REJECT(lex_oct_int, "0o+777"); + TOML11_TEST_LEX_REJECT(lex_oct_int, "0o_10" ); + + TOML11_TEST_LEX_ACCEPT(lex_integer, "0o800", "0"); + TOML11_TEST_LEX_ACCEPT(lex_integer, "-0o777", "-0"); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0o+777", "0"); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0o_10", "0"); +} + +BOOST_AUTO_TEST_CASE(test_bin_correct) +{ + TOML11_TEST_LEX_ACCEPT(lex_integer, "0b10000", "0b10000" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0b010000", "0b010000" ); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0b01_00_00", "0b01_00_00"); + TOML11_TEST_LEX_ACCEPT(lex_integer, "0b111111", "0b111111" ); +} + +BOOST_AUTO_TEST_CASE(test_bin_invalid) +{ + TOML11_TEST_LEX_ACCEPT(lex_bin_int, "0b11__11", "0b11"); + TOML11_TEST_LEX_ACCEPT(lex_bin_int, "0b11+11" , "0b11"); + + TOML11_TEST_LEX_REJECT(lex_bin_int, "-0b10000"); + TOML11_TEST_LEX_REJECT(lex_bin_int, "0b_1111" ); +} diff --git a/external/toml11/tests/test_lex_key_comment.cpp b/external/toml11/tests/test_lex_key_comment.cpp new file mode 100644 index 0000000..da123a4 --- /dev/null +++ b/external/toml11/tests/test_lex_key_comment.cpp @@ -0,0 +1,52 @@ +#include + +#include "unit_test.hpp" +#include "test_lex_aux.hpp" + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_bare_key) +{ + TOML11_TEST_LEX_ACCEPT(lex_key, "barekey", "barekey"); + TOML11_TEST_LEX_ACCEPT(lex_key, "bare-key", "bare-key"); + TOML11_TEST_LEX_ACCEPT(lex_key, "bare_key", "bare_key"); + TOML11_TEST_LEX_ACCEPT(lex_key, "1234", "1234"); +} + +BOOST_AUTO_TEST_CASE(test_quoted_key) +{ + TOML11_TEST_LEX_ACCEPT(lex_key, "\"127.0.0.1\"", "\"127.0.0.1\""); + TOML11_TEST_LEX_ACCEPT(lex_key, "\"character encoding\"", "\"character encoding\""); + + // UTF-8 codepoint of characters that looks like "key" written upside down + TOML11_TEST_LEX_ACCEPT(lex_key, "\"\xCA\x8E\xC7\x9D\xCA\x9E\"", + "\"\xCA\x8E\xC7\x9D\xCA\x9E\""); + + TOML11_TEST_LEX_ACCEPT(lex_key, "'key2'", "'key2'"); + TOML11_TEST_LEX_ACCEPT(lex_key, "'quoted \"value\"'", "'quoted \"value\"'"); +} + +BOOST_AUTO_TEST_CASE(test_dotted_key) +{ + TOML11_TEST_LEX_ACCEPT(lex_key, "physical.color", "physical.color"); + TOML11_TEST_LEX_ACCEPT(lex_key, "physical.shape", "physical.shape"); + TOML11_TEST_LEX_ACCEPT(lex_key, "x.y", "x.y"); + TOML11_TEST_LEX_ACCEPT(lex_key, "x . y", "x . y"); + TOML11_TEST_LEX_ACCEPT(lex_key, "x.y.z", "x.y.z"); + TOML11_TEST_LEX_ACCEPT(lex_key, "x. y .z", "x. y .z"); + TOML11_TEST_LEX_ACCEPT(lex_key, "x .y. z", "x .y. z"); + TOML11_TEST_LEX_ACCEPT(lex_key, "x . y . z", "x . y . z"); + TOML11_TEST_LEX_ACCEPT(lex_key, "x.y.z.w", "x.y.z.w"); + TOML11_TEST_LEX_ACCEPT(lex_key, "x. y .z. w", "x. y .z. w"); + TOML11_TEST_LEX_ACCEPT(lex_key, "x . y . z . w", "x . y . z . w"); + TOML11_TEST_LEX_ACCEPT(lex_key, "site.\"google.com\"", "site.\"google.com\""); +} + +BOOST_AUTO_TEST_CASE(test_comment) +{ + TOML11_TEST_LEX_ACCEPT(lex_comment, "# hoge", "# hoge"); + TOML11_TEST_LEX_ACCEPT(lex_comment, "# \n", "# "); + TOML11_TEST_LEX_ACCEPT(lex_comment, "# \r\n", "# "); + TOML11_TEST_LEX_ACCEPT(lex_comment, "# # \n", "# # "); +} diff --git a/external/toml11/tests/test_lex_string.cpp b/external/toml11/tests/test_lex_string.cpp new file mode 100644 index 0000000..f8f2424 --- /dev/null +++ b/external/toml11/tests/test_lex_string.cpp @@ -0,0 +1,108 @@ +#include + +#include "unit_test.hpp" +#include "test_lex_aux.hpp" + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_string) +{ + TOML11_TEST_LEX_ACCEPT(lex_string, + "\"The quick brown fox jumps over the lazy dog\"", + "\"The quick brown fox jumps over the lazy dog\""); + TOML11_TEST_LEX_ACCEPT(lex_string, + "\'The quick brown fox jumps over the lazy dog\'", + "\'The quick brown fox jumps over the lazy dog\'"); + TOML11_TEST_LEX_ACCEPT(lex_ml_basic_string, + "\"\"\"The quick brown fox \\\njumps over the lazy dog\"\"\"", + "\"\"\"The quick brown fox \\\njumps over the lazy dog\"\"\""); + TOML11_TEST_LEX_ACCEPT(lex_ml_literal_string, + "'''The quick brown fox \njumps over the lazy dog'''", + "'''The quick brown fox \njumps over the lazy dog'''"); +} + +BOOST_AUTO_TEST_CASE(test_basic_string) +{ + TOML11_TEST_LEX_ACCEPT(lex_string, + "\"GitHub Cofounder & CEO\\nLikes tater tots and beer.\"", + "\"GitHub Cofounder & CEO\\nLikes tater tots and beer.\""); + TOML11_TEST_LEX_ACCEPT(lex_string, + "\"192.168.1.1\"", + "\"192.168.1.1\""); + + TOML11_TEST_LEX_ACCEPT(lex_string, + "\"\xE4\xB8\xAD\xE5\x9B\xBD\"", // UTF-8 string (means "China" in + "\"\xE4\xB8\xAD\xE5\x9B\xBD\""); // Chinese characters) + + TOML11_TEST_LEX_ACCEPT(lex_string, + "\"You'll hate me after this - #\"", + "\"You'll hate me after this - #\""); + TOML11_TEST_LEX_ACCEPT(lex_string, + "\" And when \\\"'s are in the string, along with # \\\"\"", + "\" And when \\\"'s are in the string, along with # \\\"\""); +} + +BOOST_AUTO_TEST_CASE(test_ml_basic_string) +{ + TOML11_TEST_LEX_ACCEPT(lex_string, + "\"\"\"\nThe quick brown \\\n\n fox jumps over \\\n the lazy dog.\"\"\"", + "\"\"\"\nThe quick brown \\\n\n fox jumps over \\\n the lazy dog.\"\"\""); + TOML11_TEST_LEX_ACCEPT(lex_string, + "\"\"\"\\\n The quick brown \\\n\n fox jumps over \\\n the lazy dog.\\\n \"\"\"", + "\"\"\"\\\n The quick brown \\\n\n fox jumps over \\\n the lazy dog.\\\n \"\"\""); + + TOML11_TEST_LEX_ACCEPT(lex_string, + "\"\"\"Here are two quotation marks: \"\". Simple enough.\"\"\"", + "\"\"\"Here are two quotation marks: \"\". Simple enough.\"\"\""); + + TOML11_TEST_LEX_ACCEPT(lex_string, + "\"\"\"Here are three quotation marks: \"\"\\\".\"\"\"", + "\"\"\"Here are three quotation marks: \"\"\\\".\"\"\""); + + TOML11_TEST_LEX_ACCEPT(lex_string, + "\"\"\"Here are fifteen quotation marks: \"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\".\"\"\"", + "\"\"\"Here are fifteen quotation marks: \"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\".\"\"\""); + + TOML11_TEST_LEX_ACCEPT(lex_string, + "\"\"\"\"This,\" she said, \"is just a pointless statement.\"\"\"\"", + "\"\"\"\"This,\" she said, \"is just a pointless statement.\"\"\"\""); +} + +BOOST_AUTO_TEST_CASE(test_literal_string) +{ + TOML11_TEST_LEX_ACCEPT(lex_string, + "'C:\\Users\\nodejs\\templates'", + "'C:\\Users\\nodejs\\templates'"); + TOML11_TEST_LEX_ACCEPT(lex_string, + "'\\\\ServerX\\admin$\\system32\\'", + "'\\\\ServerX\\admin$\\system32\\'"); + TOML11_TEST_LEX_ACCEPT(lex_string, + "'Tom \"Dubs\" Preston-Werner'", + "'Tom \"Dubs\" Preston-Werner'"); + TOML11_TEST_LEX_ACCEPT(lex_string, + "'<\\i\\c*\\s*>'", + "'<\\i\\c*\\s*>'"); +} + +BOOST_AUTO_TEST_CASE(test_ml_literal_string) +{ + TOML11_TEST_LEX_ACCEPT(lex_string, + "'''I [dw]on't need \\d{2} apples'''", + "'''I [dw]on't need \\d{2} apples'''"); + TOML11_TEST_LEX_ACCEPT(lex_string, + "'''\nThe first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n'''", + "'''\nThe first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n'''"); + + TOML11_TEST_LEX_ACCEPT(lex_string, + "''''That's still pointless', she said.'''", + "''''That's still pointless', she said.'''"); + + TOML11_TEST_LEX_ACCEPT(lex_string, + "'''Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".'''", + "'''Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".'''"); + + TOML11_TEST_LEX_ACCEPT(lex_string, + "''''This,' she said, 'is just a pointless statement.''''", + "''''This,' she said, 'is just a pointless statement.''''"); +} diff --git a/external/toml11/tests/test_literals.cpp b/external/toml11/tests/test_literals.cpp new file mode 100644 index 0000000..de81f39 --- /dev/null +++ b/external/toml11/tests/test_literals.cpp @@ -0,0 +1,336 @@ +#include + +#include "unit_test.hpp" + +#include + +BOOST_AUTO_TEST_CASE(test_file_as_literal) +{ + using namespace toml::literals::toml_literals; + + { + const toml::value r{{"a", 42}, {"b", "baz"}}; + const toml::value v = R"( + a = 42 + b = "baz" + )"_toml; + + BOOST_TEST(r == v); + } + { + const toml::value r{ + {"c", 3.14}, + {"table", toml::table{{"a", 42}, {"b", "baz"}}} + }; + const toml::value v = R"( + c = 3.14 + [table] + a = 42 + b = "baz" + )"_toml; + + BOOST_TEST(r == v); + } + { + const toml::value r{ + {"table", toml::table{{"a", 42}, {"b", "baz"}}} + }; + const toml::value v = R"( + [table] + a = 42 + b = "baz" + )"_toml; + + BOOST_TEST(r == v); + } + { + const toml::value r{ + {"array_of_tables", toml::array{toml::table{}}} + }; + const toml::value v = R"( + [[array_of_tables]] + )"_toml; + + BOOST_TEST(r == v); + } +} + +BOOST_AUTO_TEST_CASE(test_value_as_literal) +{ + using namespace toml::literals::toml_literals; + + { + const toml::value v1 = "true"_toml; + const toml::value v2 = "false"_toml; + + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v2.is_boolean()); + BOOST_TEST(toml::get(v1)); + BOOST_TEST(!toml::get(v2)); + } + { + const toml::value v1 = "123_456"_toml; + const toml::value v2 = "0b0010"_toml; + const toml::value v3 = "0xDEADBEEF"_toml; + + BOOST_TEST(v1.is_integer()); + BOOST_TEST(v2.is_integer()); + BOOST_TEST(v3.is_integer()); + BOOST_TEST(toml::get(v1) == 123456); + BOOST_TEST(toml::get(v2) == 2); + BOOST_TEST(toml::get(v3) == 0xDEADBEEF); + } + { + const toml::value v1 = "3.1415"_toml; + const toml::value v2 = "6.02e+23"_toml; + + BOOST_TEST(v1.is_floating()); + BOOST_TEST(v2.is_floating()); + BOOST_TEST(toml::get(v1) == 3.1415, boost::test_tools::tolerance(0.00001)); + BOOST_TEST(toml::get(v2) == 6.02e23, boost::test_tools::tolerance(0.0001)); + } + { + const toml::value v1 = R"("foo")"_toml; + const toml::value v2 = R"('foo')"_toml; + const toml::value v3 = R"("""foo""")"_toml; + const toml::value v4 = R"('''foo''')"_toml; + + BOOST_TEST(v1.is_string()); + BOOST_TEST(v2.is_string()); + BOOST_TEST(v3.is_string()); + BOOST_TEST(v4.is_string()); + BOOST_TEST(toml::get(v1) == "foo"); + BOOST_TEST(toml::get(v2) == "foo"); + BOOST_TEST(toml::get(v3) == "foo"); + BOOST_TEST(toml::get(v4) == "foo"); + } + { + { + const toml::value v1 = R"([1,2,3])"_toml; + BOOST_TEST(v1.is_array()); + const bool result = (toml::get>(v1) == std::vector{1,2,3}); + BOOST_TEST(result); + } + { + const toml::value v2 = R"([1,])"_toml; + BOOST_TEST(v2.is_array()); + const bool result = (toml::get>(v2) == std::vector{1}); + BOOST_TEST(result); + } + { + const toml::value v3 = R"([[1,]])"_toml; + BOOST_TEST(v3.is_array()); + const bool result = (toml::get>(toml::get(v3).front()) == std::vector{1}); + BOOST_TEST(result); + } + { + const toml::value v4 = R"([[1],])"_toml; + BOOST_TEST(v4.is_array()); + const bool result = (toml::get>(toml::get(v4).front()) == std::vector{1}); + BOOST_TEST(result); + } + } + { + const toml::value v1 = R"({a = 42})"_toml; + + BOOST_TEST(v1.is_table()); + const bool result = toml::get>(v1) == + std::map{{"a", 42}}; + BOOST_TEST(result); + } + { + const toml::value v1 = "1979-05-27"_toml; + + BOOST_TEST(v1.is_local_date()); + BOOST_TEST(toml::get(v1) == + toml::local_date(1979, toml::month_t::May, 27)); + } + { + const toml::value v1 = "12:00:00"_toml; + + BOOST_TEST(v1.is_local_time()); + const bool result = toml::get(v1) == std::chrono::hours(12); + BOOST_TEST(result); + } + { + const toml::value v1 = "1979-05-27T07:32:00"_toml; + BOOST_TEST(v1.is_local_datetime()); + BOOST_TEST(toml::get(v1) == + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0))); + } + { + const toml::value v1 = "1979-05-27T07:32:00Z"_toml; + BOOST_TEST(v1.is_offset_datetime()); + BOOST_TEST(toml::get(v1) == + toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0), toml::time_offset(0, 0))); + } +} + +BOOST_AUTO_TEST_CASE(test_file_as_u8_literal) +{ + using namespace toml::literals::toml_literals; + + { + const toml::value r{{"a", 42}, {"b", "baz"}}; + const toml::value v = u8R"( + a = 42 + b = "baz" + )"_toml; + + BOOST_TEST(r == v); + } + { + const toml::value r{ + {"c", 3.14}, + {"table", toml::table{{"a", 42}, {"b", "baz"}}} + }; + const toml::value v = u8R"( + c = 3.14 + [table] + a = 42 + b = "baz" + )"_toml; + + BOOST_TEST(r == v); + } + { + const toml::value r{ + {"table", toml::table{{"a", 42}, {"b", "baz"}}} + }; + const toml::value v = u8R"( + [table] + a = 42 + b = "baz" + )"_toml; + + BOOST_TEST(r == v); + } + { + const toml::value r{ + {"array_of_tables", toml::array{toml::table{}}} + }; + const toml::value v = u8R"( + [[array_of_tables]] + )"_toml; + + BOOST_TEST(r == v); + } +} + +BOOST_AUTO_TEST_CASE(test_value_as_u8_literal) +{ + using namespace toml::literals::toml_literals; + + { + const toml::value v1 = u8"true"_toml; + const toml::value v2 = u8"false"_toml; + + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v2.is_boolean()); + BOOST_TEST(toml::get(v1)); + BOOST_TEST(!toml::get(v2)); + } + { + const toml::value v1 = u8"123_456"_toml; + const toml::value v2 = u8"0b0010"_toml; + const toml::value v3 = u8"0xDEADBEEF"_toml; + + BOOST_TEST(v1.is_integer()); + BOOST_TEST(v2.is_integer()); + BOOST_TEST(v3.is_integer()); + BOOST_TEST(toml::get(v1) == 123456); + BOOST_TEST(toml::get(v2) == 2); + BOOST_TEST(toml::get(v3) == 0xDEADBEEF); + } + { + const toml::value v1 = u8"3.1415"_toml; + const toml::value v2 = u8"6.02e+23"_toml; + + BOOST_TEST(v1.is_floating()); + BOOST_TEST(v2.is_floating()); + BOOST_TEST(toml::get(v1) == 3.1415, boost::test_tools::tolerance(0.00001)); + BOOST_TEST(toml::get(v2) == 6.02e23, boost::test_tools::tolerance(0.0001)); + } + { + const toml::value v1 = u8R"("foo")"_toml; + const toml::value v2 = u8R"('foo')"_toml; + const toml::value v3 = u8R"("""foo""")"_toml; + const toml::value v4 = u8R"('''foo''')"_toml; + const toml::value v5 = u8R"("ひらがな")"_toml; + + BOOST_TEST(v1.is_string()); + BOOST_TEST(v2.is_string()); + BOOST_TEST(v3.is_string()); + BOOST_TEST(v4.is_string()); + BOOST_TEST(v5.is_string()); + BOOST_TEST(toml::get(v1) == "foo"); + BOOST_TEST(toml::get(v2) == "foo"); + BOOST_TEST(toml::get(v3) == "foo"); + BOOST_TEST(toml::get(v4) == "foo"); + BOOST_TEST(toml::get(v5) == "\xE3\x81\xB2\xE3\x82\x89\xE3\x81\x8C\xE3\x81\xAA"); + } + { + { + const toml::value v1 = u8R"([1,2,3])"_toml; + BOOST_TEST(v1.is_array()); + const bool result = (toml::get>(v1) == std::vector{1,2,3}); + BOOST_TEST(result); + } + { + const toml::value v2 = u8R"([1,])"_toml; + BOOST_TEST(v2.is_array()); + const bool result = (toml::get>(v2) == std::vector{1}); + BOOST_TEST(result); + } + { + const toml::value v3 = u8R"([[1,]])"_toml; + BOOST_TEST(v3.is_array()); + const bool result = (toml::get>(toml::get(v3).front()) == std::vector{1}); + BOOST_TEST(result); + } + { + const toml::value v4 = u8R"([[1],])"_toml; + BOOST_TEST(v4.is_array()); + const bool result = (toml::get>(toml::get(v4).front()) == std::vector{1}); + BOOST_TEST(result); + } + } + { + const toml::value v1 = u8R"({a = 42})"_toml; + + BOOST_TEST(v1.is_table()); + const bool result = toml::get>(v1) == + std::map{{"a", 42}}; + BOOST_TEST(result); + } + { + const toml::value v1 = u8"1979-05-27"_toml; + + BOOST_TEST(v1.is_local_date()); + BOOST_TEST(toml::get(v1) == + toml::local_date(1979, toml::month_t::May, 27)); + } + { + const toml::value v1 = u8"12:00:00"_toml; + + BOOST_TEST(v1.is_local_time()); + const bool result = toml::get(v1) == std::chrono::hours(12); + BOOST_TEST(result); + } + { + const toml::value v1 = u8"1979-05-27T07:32:00"_toml; + BOOST_TEST(v1.is_local_datetime()); + BOOST_TEST(toml::get(v1) == + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0))); + } + { + const toml::value v1 = u8"1979-05-27T07:32:00Z"_toml; + BOOST_TEST(v1.is_offset_datetime()); + BOOST_TEST(toml::get(v1) == + toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0), toml::time_offset(0, 0))); + } +} diff --git a/external/toml11/tests/test_multiple_translation_unit_1.cpp b/external/toml11/tests/test_multiple_translation_unit_1.cpp new file mode 100644 index 0000000..08a4f98 --- /dev/null +++ b/external/toml11/tests/test_multiple_translation_unit_1.cpp @@ -0,0 +1,11 @@ +#include + +int read_a(const toml::table&); + +int main() +{ + const std::string content("a = 0"); + std::istringstream iss(content); + const auto data = toml::parse(iss, "test_multiple_translation_unit.toml"); + return read_a(toml::get(data)); +} diff --git a/external/toml11/tests/test_multiple_translation_unit_2.cpp b/external/toml11/tests/test_multiple_translation_unit_2.cpp new file mode 100644 index 0000000..2a4cc32 --- /dev/null +++ b/external/toml11/tests/test_multiple_translation_unit_2.cpp @@ -0,0 +1,6 @@ +#include + +int read_a(const toml::table& t) +{ + return toml::get(t.at("a")); +} diff --git a/external/toml11/tests/test_parse_array.cpp b/external/toml11/tests/test_parse_array.cpp new file mode 100644 index 0000000..2d118c2 --- /dev/null +++ b/external/toml11/tests/test_parse_array.cpp @@ -0,0 +1,288 @@ +#include + +#include "unit_test.hpp" +#include "test_parse_aux.hpp" + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_oneline_array) +{ + TOML11_TEST_PARSE_EQUAL_VAT(parse_array, "[]", array()); + { + array a(5); + a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4); + a[3] = toml::value(1); a[4] = toml::value(5); + TOML11_TEST_PARSE_EQUAL_VAT(parse_array, "[3,1,4,1,5]", a); + } + { + array a(3); + a[0] = toml::value("foo"); a[1] = toml::value("bar"); + a[2] = toml::value("baz"); + TOML11_TEST_PARSE_EQUAL_VAT(parse_array, "[\"foo\", \"bar\", \"baz\"]", a); + } + { + array a(5); + a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4); + a[3] = toml::value(1); a[4] = toml::value(5); + TOML11_TEST_PARSE_EQUAL_VAT(parse_array, "[3,1,4,1,5,]", a); + } + { + array a(3); + a[0] = toml::value("foo"); a[1] = toml::value("bar"); + a[2] = toml::value("baz"); + TOML11_TEST_PARSE_EQUAL_VAT(parse_array, "[\"foo\", \"bar\", \"baz\",]", a); + } +} + +BOOST_AUTO_TEST_CASE(test_oneline_array_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[]", toml::value(array())); + { + array a(5); + a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4); + a[3] = toml::value(1); a[4] = toml::value(5); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,1,4,1,5]", toml::value(a)); + } + { + array a(3); + a[0] = toml::value("foo"); a[1] = toml::value("bar"); + a[2] = toml::value("baz"); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\", \"bar\", \"baz\"]", toml::value(a)); + } + { + array a(5); + a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4); + a[3] = toml::value(1); a[4] = toml::value(5); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,1,4,1,5,]", toml::value(a)); + } + { + array a(3); + a[0] = toml::value("foo"); a[1] = toml::value("bar"); + a[2] = toml::value("baz"); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\", \"bar\", \"baz\",]", toml::value(a)); + } +} + +BOOST_AUTO_TEST_CASE(test_multiline_array) +{ + TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[\n#comment\n]", typename basic_value< discard_comments>::array_type()); + TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[\n#comment\n]", typename basic_value::array_type()); + + { + typename basic_value::array_type a(5); + a[0] = basic_value(3); + a[1] = basic_value(1); + a[2] = basic_value(4); + a[3] = basic_value(1); + a[4] = basic_value(5); + TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[3,\n1,\n4,\n1,\n5]", a); + } + { + typename basic_value::array_type a(5); + a[0] = basic_value(3); + a[1] = basic_value(1); + a[2] = basic_value(4); + a[3] = basic_value(1); + a[4] = basic_value(5); + TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[3,\n1,\n4,\n1,\n5]", a); + } + + { + typename basic_value::array_type a(5); + a[0] = basic_value(3); + a[1] = basic_value(1); + a[2] = basic_value(4); + a[3] = basic_value(1); + a[4] = basic_value(5); + TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5 #comment\n]", a); + } + { + typename basic_value::array_type a(5); + a[0] = basic_value(3, {"comment"}); + a[1] = basic_value(1, {"comment"}); + a[2] = basic_value(4, {"comment"}); + a[3] = basic_value(1, {"comment"}); + a[4] = basic_value(5, {"comment"}); + TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5 #comment\n]", a); + } + + + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo"); + a[1] = basic_value("bar"); + a[2] = basic_value("baz"); + TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[\"foo\",\n\"bar\",\n\"baz\"]", a); + } + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo"); + a[1] = basic_value("bar"); + a[2] = basic_value("baz"); + TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[\"foo\",\n\"bar\",\n\"baz\"]", a); + } + + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo"); + a[1] = basic_value("b#r"); + a[2] = basic_value("b#z"); + TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", a); + } + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo", {"comment"}); + a[1] = basic_value("b#r", {"comment"}); + a[2] = basic_value("b#z", {"comment"}); + TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", a); + } +} + +BOOST_AUTO_TEST_CASE(test_multiline_array_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\n#comment\n]", basic_value< discard_comments>(typename basic_value< discard_comments>::array_type())); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\n#comment\n]", basic_value(typename basic_value::array_type())); + + { + typename basic_value::array_type a(5); + a[0] = basic_value(3); + a[1] = basic_value(1); + a[2] = basic_value(4); + a[3] = basic_value(1); + a[4] = basic_value(5); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[3,\n1,\n4,\n1,\n5]", basic_value(a)); + } + { + typename basic_value::array_type a(5); + a[0] = basic_value(3); + a[1] = basic_value(1); + a[2] = basic_value(4); + a[3] = basic_value(1); + a[4] = basic_value(5); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[3,\n1,\n4,\n1,\n5]", basic_value(a)); + } + + { + typename basic_value::array_type a(5); + a[0] = basic_value(3); + a[1] = basic_value(1); + a[2] = basic_value(4); + a[3] = basic_value(1); + a[4] = basic_value(5); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5 #comment\n]", basic_value(a)); + } + { + typename basic_value::array_type a(5); + a[0] = basic_value(3, {"comment"}); + a[1] = basic_value(1, {"comment"}); + a[2] = basic_value(4, {"comment"}); + a[3] = basic_value(1, {"comment"}); + a[4] = basic_value(5, {"comment"}); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5 #comment\n]", basic_value(a)); + } + + + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo"); + a[1] = basic_value("bar"); + a[2] = basic_value("baz"); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\"foo\",\n\"bar\",\n\"baz\"]", basic_value(a)); + } + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo"); + a[1] = basic_value("bar"); + a[2] = basic_value("baz"); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\"foo\",\n\"bar\",\n\"baz\"]", basic_value(a)); + } + + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo"); + a[1] = basic_value("b#r"); + a[2] = basic_value("b#z"); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", basic_value(a)); + } + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo", {"comment"}); + a[1] = basic_value("b#r", {"comment"}); + a[2] = basic_value("b#z", {"comment"}); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", basic_value(a)); + } + +} + +BOOST_AUTO_TEST_CASE(test_heterogeneous_array) +{ +#ifndef TOML11_USE_UNRELEASED_TOML_FEATURES + BOOST_TEST_MESSAGE("In strict TOML v0.5.0, heterogeneous arrays are not allowed."); +#else + { + array a(5); + a[0] = toml::value("foo"); + a[1] = toml::value(3.14); + a[2] = toml::value(42); + a[3] = toml::value{toml::value("array"), toml::value("of"), toml::value("hetero-array"), toml::value(1)}; + a[4] = toml::value{{"key", "value"}}; + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\", 3.14, 42, [\"array\", \"of\", \"hetero-array\", 1], {key = \"value\"}]", toml::value(a)); + } + { + array a(5); + a[0] = toml::value("foo"); + a[1] = toml::value(3.14); + a[2] = toml::value(42); + a[3] = toml::value{toml::value("array"), toml::value("of"), toml::value("hetero-array"), toml::value(1)}; + a[4] = toml::value{{"key", "value"}}; + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\",\n 3.14,\n 42,\n [\"array\", \"of\", \"hetero-array\", 1],\n {key = \"value\"},\n]", toml::value(a)); + } + { + array a(5); + a[0] = toml::value("foo"); + a[1] = toml::value(3.14); + a[2] = toml::value(42); + a[3] = toml::value{toml::value("array"), toml::value("of"), toml::value("hetero-array"), toml::value(1)}; + a[4] = toml::value{{"key", "value"}}; + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\",#comment\n 3.14,#comment\n 42,#comment\n [\"array\", \"of\", \"hetero-array\", 1],#comment\n {key = \"value\"},#comment\n]#comment", toml::value(a)); + } + { + array a(5); + a[0] = toml::value("foo"); + a[1] = toml::value(3.14); + a[2] = toml::value(42); + a[3] = toml::value{toml::value("array"), toml::value("of"), toml::value("hetero-array"), toml::value(1)}; + a[4] = toml::value{{"key", "value"}}; + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\",\n 3.14,\n 42,\n [\"array\",\n \"of\",\n \"hetero-array\",\n 1],\n {key = \"value\"},\n]", toml::value(a)); + } +#endif +} + +BOOST_AUTO_TEST_CASE(test_comments_after_comma) +{ + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo"); + a[1] = basic_value("bar"); + a[2] = basic_value("baz"); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, + "[ \"foo\" # comment\n" + ", \"bar\" # comment\n" + ", \"baz\" # comment\n" + "]", basic_value(a)); + } + + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo", {" comment"}); + a[1] = basic_value("bar", {" comment"}); + a[2] = basic_value("baz", {" comment"}); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, + "[ \"foo\" # comment\n" + ", \"bar\" # comment\n" + ", \"baz\" # comment\n" + "]", basic_value(a)); + } + +} diff --git a/external/toml11/tests/test_parse_aux.hpp b/external/toml11/tests/test_parse_aux.hpp new file mode 100644 index 0000000..331d4c8 --- /dev/null +++ b/external/toml11/tests/test_parse_aux.hpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +// some of the parsers returns not only a value but also a region. +#define TOML11_TEST_PARSE_EQUAL(psr, tkn, expct) \ +do { \ + const std::string token(tkn); \ + toml::detail::location loc("test", token); \ + const auto result = psr(loc); \ + BOOST_TEST(result.is_ok()); \ + if(result.is_ok()){ \ + BOOST_TEST(result.unwrap().first == expct); \ + } else { \ + std::cerr << "parser " << #psr << " failed with input `"; \ + std::cerr << token << "`.\n"; \ + std::cerr << "reason: " << result.unwrap_err() << '\n'; \ + } \ +} while(false); \ +/**/ + +#define TOML11_TEST_PARSE_EQUAL_VAT(psr, tkn, expct) \ +do { \ + const std::string token(tkn); \ + toml::detail::location loc("test", token); \ + const auto result = psr(loc, 0); \ + BOOST_TEST(result.is_ok()); \ + if(result.is_ok()){ \ + BOOST_TEST(result.unwrap().first == expct); \ + } else { \ + std::cerr << "parser " << #psr << " failed with input `"; \ + std::cerr << token << "`.\n"; \ + std::cerr << "reason: " << result.unwrap_err() << '\n'; \ + } \ +} while(false); \ +/**/ + +#define TOML11_TEST_PARSE_EQUAL_VALUE(psr, tkn, expct) \ +do { \ + const std::string token(tkn); \ + toml::detail::location loc("test", token); \ + const auto result = psr(loc, 0); \ + BOOST_TEST(result.is_ok()); \ + if(result.is_ok()){ \ + BOOST_TEST(result.unwrap() == expct); \ + } else { \ + std::cerr << "parse_value failed with input `"; \ + std::cerr << token << "`.\n"; \ + std::cerr << "reason: " << result.unwrap_err() << '\n'; \ + } \ +} while(false); \ +/**/ + diff --git a/external/toml11/tests/test_parse_boolean.cpp b/external/toml11/tests/test_parse_boolean.cpp new file mode 100644 index 0000000..5ed128c --- /dev/null +++ b/external/toml11/tests/test_parse_boolean.cpp @@ -0,0 +1,19 @@ +#include + +#include "unit_test.hpp" +#include "test_parse_aux.hpp" + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_boolean) +{ + TOML11_TEST_PARSE_EQUAL(parse_boolean, "true", true); + TOML11_TEST_PARSE_EQUAL(parse_boolean, "false", false); +} + +BOOST_AUTO_TEST_CASE(test_boolean_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "true", toml::value( true)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "false", toml::value(false)); +} diff --git a/external/toml11/tests/test_parse_datetime.cpp b/external/toml11/tests/test_parse_datetime.cpp new file mode 100644 index 0000000..46bd78c --- /dev/null +++ b/external/toml11/tests/test_parse_datetime.cpp @@ -0,0 +1,246 @@ +#include + +#include "unit_test.hpp" +#include "test_parse_aux.hpp" + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_time) +{ + TOML11_TEST_PARSE_EQUAL(parse_local_time, "07:32:00", toml::local_time(7, 32, 0)); + TOML11_TEST_PARSE_EQUAL(parse_local_time, "07:32:00.99", toml::local_time(7, 32, 0, 990, 0)); + TOML11_TEST_PARSE_EQUAL(parse_local_time, "07:32:00.999", toml::local_time(7, 32, 0, 999, 0)); + TOML11_TEST_PARSE_EQUAL(parse_local_time, "07:32:00.999999", toml::local_time(7, 32, 0, 999, 999)); + + + TOML11_TEST_PARSE_EQUAL(parse_local_time, "00:00:00.000000", toml::local_time( 0, 0, 0, 0, 0)); + TOML11_TEST_PARSE_EQUAL(parse_local_time, "23:59:59.999999", toml::local_time(23, 59, 59, 999, 999)); + TOML11_TEST_PARSE_EQUAL(parse_local_time, "23:59:60.999999", toml::local_time(23, 59, 60, 999, 999)); // leap second +} + +BOOST_AUTO_TEST_CASE(test_time_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "07:32:00", toml::value(toml::local_time(7, 32, 0))); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "07:32:00.99", toml::value(toml::local_time(7, 32, 0, 990, 0))); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "07:32:00.999", toml::value(toml::local_time(7, 32, 0, 999, 0))); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "07:32:00.999999", toml::value(toml::local_time(7, 32, 0, 999, 999))); + + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "00:00:00.000000", toml::value(toml::local_time( 0, 0, 0, 0, 0))); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "23:59:59.999999", toml::value(toml::local_time(23, 59, 59, 999, 999))); + + std::istringstream stream1(std::string("invalid-datetime = 24:00:00")); + std::istringstream stream2(std::string("invalid-datetime = 00:60:00")); + std::istringstream stream3(std::string("invalid-datetime = 00:00:61")); + BOOST_CHECK_THROW(toml::parse(stream1), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream2), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream3), toml::syntax_error); +} + +BOOST_AUTO_TEST_CASE(test_date) +{ + TOML11_TEST_PARSE_EQUAL(parse_local_date, "1979-05-27", toml::local_date(1979, toml::month_t::May, 27)); + + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-01-01", toml::local_date(2000, toml::month_t::Jan, 1)); + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-01-31", toml::local_date(2000, toml::month_t::Jan, 31)); + std::istringstream stream1_1(std::string("invalid-datetime = 2000-01-00")); + std::istringstream stream1_2(std::string("invalid-datetime = 2000-01-32")); + BOOST_CHECK_THROW(toml::parse(stream1_1), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream1_2), toml::syntax_error); + + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-02-01", toml::local_date(2000, toml::month_t::Feb, 1)); + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-02-29", toml::local_date(2000, toml::month_t::Feb, 29)); + std::istringstream stream2_1(std::string("invalid-datetime = 2000-02-00")); + std::istringstream stream2_2(std::string("invalid-datetime = 2000-02-30")); + BOOST_CHECK_THROW(toml::parse(stream2_1), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream2_2), toml::syntax_error); + + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2001-02-28", toml::local_date(2001, toml::month_t::Feb, 28)); + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2004-02-29", toml::local_date(2004, toml::month_t::Feb, 29)); + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2100-02-28", toml::local_date(2100, toml::month_t::Feb, 28)); + std::istringstream stream2_3(std::string("invalid-datetime = 2001-02-29")); + std::istringstream stream2_4(std::string("invalid-datetime = 2004-02-30")); + std::istringstream stream2_5(std::string("invalid-datetime = 2100-02-29")); + BOOST_CHECK_THROW(toml::parse(stream2_3), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream2_4), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream2_5), toml::syntax_error); + + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-03-01", toml::local_date(2000, toml::month_t::Mar, 1)); + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-03-31", toml::local_date(2000, toml::month_t::Mar, 31)); + std::istringstream stream3_1(std::string("invalid-datetime = 2000-03-00")); + std::istringstream stream3_2(std::string("invalid-datetime = 2000-03-32")); + BOOST_CHECK_THROW(toml::parse(stream3_1), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream3_2), toml::syntax_error); + + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-04-01", toml::local_date(2000, toml::month_t::Apr, 1)); + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-04-30", toml::local_date(2000, toml::month_t::Apr, 30)); + std::istringstream stream4_1(std::string("invalid-datetime = 2000-04-00")); + std::istringstream stream4_2(std::string("invalid-datetime = 2000-04-31")); + BOOST_CHECK_THROW(toml::parse(stream4_1), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream4_2), toml::syntax_error); + + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-05-01", toml::local_date(2000, toml::month_t::May, 1)); + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-05-31", toml::local_date(2000, toml::month_t::May, 31)); + std::istringstream stream5_1(std::string("invalid-datetime = 2000-05-00")); + std::istringstream stream5_2(std::string("invalid-datetime = 2000-05-32")); + BOOST_CHECK_THROW(toml::parse(stream5_1), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream5_2), toml::syntax_error); + + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-06-01", toml::local_date(2000, toml::month_t::Jun, 1)); + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-06-30", toml::local_date(2000, toml::month_t::Jun, 30)); + std::istringstream stream6_1(std::string("invalid-datetime = 2000-06-00")); + std::istringstream stream6_2(std::string("invalid-datetime = 2000-06-31")); + BOOST_CHECK_THROW(toml::parse(stream6_1), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream6_2), toml::syntax_error); + + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-07-01", toml::local_date(2000, toml::month_t::Jul, 1)); + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-07-31", toml::local_date(2000, toml::month_t::Jul, 31)); + std::istringstream stream7_1(std::string("invalid-datetime = 2000-07-00")); + std::istringstream stream7_2(std::string("invalid-datetime = 2000-07-32")); + BOOST_CHECK_THROW(toml::parse(stream7_1), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream7_2), toml::syntax_error); + + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-08-01", toml::local_date(2000, toml::month_t::Aug, 1)); + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-08-31", toml::local_date(2000, toml::month_t::Aug, 31)); + std::istringstream stream8_1(std::string("invalid-datetime = 2000-08-00")); + std::istringstream stream8_2(std::string("invalid-datetime = 2000-08-32")); + BOOST_CHECK_THROW(toml::parse(stream8_1), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream8_2), toml::syntax_error); + + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-09-01", toml::local_date(2000, toml::month_t::Sep, 1)); + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-09-30", toml::local_date(2000, toml::month_t::Sep, 30)); + std::istringstream stream9_1(std::string("invalid-datetime = 2000-09-00")); + std::istringstream stream9_2(std::string("invalid-datetime = 2000-09-31")); + BOOST_CHECK_THROW(toml::parse(stream9_1), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream9_2), toml::syntax_error); + + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-10-01", toml::local_date(2000, toml::month_t::Oct, 1)); + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-10-31", toml::local_date(2000, toml::month_t::Oct, 31)); + std::istringstream stream10_1(std::string("invalid-datetime = 2000-10-00")); + std::istringstream stream10_2(std::string("invalid-datetime = 2000-10-32")); + BOOST_CHECK_THROW(toml::parse(stream10_1), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream10_2), toml::syntax_error); + + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-11-01", toml::local_date(2000, toml::month_t::Nov, 1)); + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-11-30", toml::local_date(2000, toml::month_t::Nov, 30)); + std::istringstream stream11_1(std::string("invalid-datetime = 2000-11-00")); + std::istringstream stream11_2(std::string("invalid-datetime = 2000-11-31")); + BOOST_CHECK_THROW(toml::parse(stream11_1), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream11_2), toml::syntax_error); + + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-12-01", toml::local_date(2000, toml::month_t::Dec, 1)); + TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-12-31", toml::local_date(2000, toml::month_t::Dec, 31)); + std::istringstream stream12_1(std::string("invalid-datetime = 2000-12-00")); + std::istringstream stream12_2(std::string("invalid-datetime = 2000-12-32")); + BOOST_CHECK_THROW(toml::parse(stream12_1), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream12_2), toml::syntax_error); + + std::istringstream stream13_1(std::string("invalid-datetime = 2000-13-01")); + BOOST_CHECK_THROW(toml::parse(stream13_1), toml::syntax_error); + std::istringstream stream0_1(std::string("invalid-datetime = 2000-00-01")); + BOOST_CHECK_THROW(toml::parse(stream0_1), toml::syntax_error); +} + +BOOST_AUTO_TEST_CASE(test_date_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27", value(toml::local_date(1979, toml::month_t::May, 27))); +} + +BOOST_AUTO_TEST_CASE(test_datetime) +{ + TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27T07:32:00", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0))); + TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27T07:32:00.99", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0))); + TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27T07:32:00.999999", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999))); + + TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27t07:32:00", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0))); + TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27t07:32:00.99", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0))); + TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27t07:32:00.999999", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999))); + + TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27 07:32:00", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0))); + TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27 07:32:00.99", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0))); + TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27 07:32:00.999999", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999))); +} + +BOOST_AUTO_TEST_CASE(test_datetime_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00", + toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0)))); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.99", + toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0)))); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.999999", + toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999)))); + + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27t07:32:00", + toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0)))); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27t07:32:00.99", + toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0)))); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27t07:32:00.999999", + toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999)))); + + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27 07:32:00", + toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0)))); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27 07:32:00.99", + toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0)))); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27 07:32:00.999999", + toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999)))); +} + +BOOST_AUTO_TEST_CASE(test_offset_datetime) +{ + TOML11_TEST_PARSE_EQUAL(parse_offset_datetime, "1979-05-27T07:32:00Z", + toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0), toml::time_offset(0, 0))); + TOML11_TEST_PARSE_EQUAL(parse_offset_datetime, "1979-05-27T07:32:00.99Z", + toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 990, 0), toml::time_offset(0, 0))); + TOML11_TEST_PARSE_EQUAL(parse_offset_datetime, "1979-05-27T07:32:00.999999Z", + toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 999, 999), toml::time_offset(0, 0))); + + TOML11_TEST_PARSE_EQUAL(parse_offset_datetime, "1979-05-27T07:32:00+09:00", + toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0), toml::time_offset(9, 0))); + TOML11_TEST_PARSE_EQUAL(parse_offset_datetime, "1979-05-27T07:32:00.99+09:00", + toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 990, 0), toml::time_offset(9, 0))); + TOML11_TEST_PARSE_EQUAL(parse_offset_datetime, "1979-05-27T07:32:00.999999+09:00", + toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 999, 999), toml::time_offset(9, 0))); + + std::istringstream stream1(std::string("invalid-datetime = 2000-01-01T00:00:00+24:00")); + std::istringstream stream2(std::string("invalid-datetime = 2000-01-01T00:00:00+00:60")); + BOOST_CHECK_THROW(toml::parse(stream1), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(stream2), toml::syntax_error); +} + +BOOST_AUTO_TEST_CASE(test_offset_datetime_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00Z", + toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0), toml::time_offset(0, 0)))); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.99Z", + toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 990, 0), toml::time_offset(0, 0)))); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.999999Z", + toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 999, 999), toml::time_offset(0, 0)))); + + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00+09:00", + toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0), toml::time_offset(9, 0)))); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.99+09:00", + toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 990, 0), toml::time_offset(9, 0)))); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.999999+09:00", + toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 999, 999), toml::time_offset(9, 0)))); +} diff --git a/external/toml11/tests/test_parse_file.cpp b/external/toml11/tests/test_parse_file.cpp new file mode 100644 index 0000000..2c45670 --- /dev/null +++ b/external/toml11/tests/test_parse_file.cpp @@ -0,0 +1,1009 @@ +#include + +#include "unit_test.hpp" + +#include +#include +#include +#include + +BOOST_AUTO_TEST_CASE(test_example) +{ + const auto data = toml::parse(testinput("example.toml")); + + BOOST_TEST(toml::find(data, "title") == "TOML Example"); + const auto& owner = toml::find(data, "owner"); + { + BOOST_TEST(toml::find(owner, "name") == "Tom Preston-Werner"); + BOOST_TEST(toml::find(owner, "organization") == "GitHub"); + BOOST_TEST(toml::find(owner, "bio") == + "GitHub Cofounder & CEO\nLikes tater tots and beer."); + BOOST_TEST(toml::find(owner, "dob") == + toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0), toml::time_offset(0, 0))); + } + + const auto& database = toml::find(data, "database"); + { + BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); + const std::vector expected_ports{8001, 8001, 8002}; + BOOST_CHECK(toml::find>(database, "ports") == expected_ports); + BOOST_TEST(toml::find(database, "connection_max") == 5000); + BOOST_TEST(toml::find(database, "enabled") == true); + } + + const auto& servers = toml::find(data, "servers"); + { + toml::table alpha = toml::find(servers, "alpha"); + BOOST_TEST(toml::get(alpha.at("ip")) == "10.0.0.1"); + BOOST_TEST(toml::get(alpha.at("dc")) == "eqdc10"); + + toml::table beta = toml::find(servers, "beta"); + BOOST_TEST(toml::get(beta.at("ip")) == "10.0.0.2"); + BOOST_TEST(toml::get(beta.at("dc")) == "eqdc10"); + BOOST_TEST(toml::get(beta.at("country")) == "\xE4\xB8\xAD\xE5\x9B\xBD"); + } + + const auto& clients = toml::find(data, "clients"); + { + toml::array clients_data = toml::find(clients, "data"); + + std::vector expected_name{"gamma", "delta"}; + BOOST_CHECK(toml::get>(clients_data.at(0)) == expected_name); + + std::vector expected_number{1, 2}; + BOOST_CHECK(toml::get>(clients_data.at(1)) == expected_number); + + std::vector expected_hosts{"alpha", "omega"}; + BOOST_CHECK(toml::find>(clients, "hosts") == expected_hosts); + } + + std::vector products = + toml::find>(data, "products"); + { + BOOST_TEST(toml::get(products.at(0).at("name")) == "Hammer"); + BOOST_TEST(toml::get(products.at(0).at("sku")) == 738594937); + + BOOST_TEST(toml::get(products.at(1).at("name")) == "Nail"); + BOOST_TEST(toml::get(products.at(1).at("sku")) == 284758393); + BOOST_TEST(toml::get(products.at(1).at("color")) == "gray"); + } +} + +BOOST_AUTO_TEST_CASE(test_example_stream) +{ + std::ifstream ifs(testinput("example.toml"), std::ios::binary); + const auto data = toml::parse(ifs); + + BOOST_TEST(toml::find(data, "title") == "TOML Example"); + const auto& owner = toml::find(data, "owner"); + { + BOOST_TEST(toml::find(owner, "name") == "Tom Preston-Werner"); + BOOST_TEST(toml::find(owner, "organization") == "GitHub"); + BOOST_TEST(toml::find(owner, "bio") == + "GitHub Cofounder & CEO\nLikes tater tots and beer."); + BOOST_TEST(toml::find(owner, "dob") == + toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0), toml::time_offset(0, 0))); + } + + const auto& database = toml::find(data, "database"); + { + BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); + const std::vector expected_ports{8001, 8001, 8002}; + BOOST_CHECK(toml::find>(database, "ports") == expected_ports); + BOOST_TEST(toml::find(database, "connection_max") == 5000); + BOOST_TEST(toml::find(database, "enabled") == true); + } + + const auto& servers = toml::find(data, "servers"); + { + toml::table alpha = toml::find(servers, "alpha"); + BOOST_TEST(toml::get(alpha.at("ip")) == "10.0.0.1"); + BOOST_TEST(toml::get(alpha.at("dc")) == "eqdc10"); + + toml::table beta = toml::find(servers, "beta"); + BOOST_TEST(toml::get(beta.at("ip")) == "10.0.0.2"); + BOOST_TEST(toml::get(beta.at("dc")) == "eqdc10"); + BOOST_TEST(toml::get(beta.at("country")) == "\xE4\xB8\xAD\xE5\x9B\xBD"); + } + + const auto& clients = toml::find(data, "clients"); + { + toml::array clients_data = toml::find(clients, "data"); + std::vector expected_name{"gamma", "delta"}; + BOOST_CHECK(toml::get>(clients_data.at(0)) == expected_name); + + std::vector expected_number{1, 2}; + BOOST_CHECK(toml::get>(clients_data.at(1)) == expected_number); + + std::vector expected_hosts{"alpha", "omega"}; + BOOST_CHECK(toml::find>(clients, "hosts") == expected_hosts); + } + + std::vector products = + toml::find>(data, "products"); + { + BOOST_TEST(toml::get(products.at(0).at("name")) == + "Hammer"); + BOOST_TEST(toml::get(products.at(0).at("sku")) == + 738594937); + + BOOST_TEST(toml::get(products.at(1).at("name")) == + "Nail"); + BOOST_TEST(toml::get(products.at(1).at("sku")) == + 284758393); + BOOST_TEST(toml::get(products.at(1).at("color")) == + "gray"); + } +} + +BOOST_AUTO_TEST_CASE(test_example_file_pointer) +{ + FILE * file = fopen(testinput("example.toml").c_str(), "rb"); + const auto data = toml::parse(file, "toml/tests/example.toml"); + fclose(file); + + BOOST_TEST(toml::find(data, "title") == "TOML Example"); + const auto& owner = toml::find(data, "owner"); + { + BOOST_TEST(toml::find(owner, "name") == "Tom Preston-Werner"); + BOOST_TEST(toml::find(owner, "organization") == "GitHub"); + BOOST_TEST(toml::find(owner, "bio") == + "GitHub Cofounder & CEO\nLikes tater tots and beer."); + BOOST_TEST(toml::find(owner, "dob") == + toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0), toml::time_offset(0, 0))); + } + + const auto& database = toml::find(data, "database"); + { + BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); + const std::vector expected_ports{8001, 8001, 8002}; + BOOST_CHECK(toml::find>(database, "ports") == expected_ports); + BOOST_TEST(toml::find(database, "connection_max") == 5000); + BOOST_TEST(toml::find(database, "enabled") == true); + } + + const auto& servers = toml::find(data, "servers"); + { + toml::table alpha = toml::find(servers, "alpha"); + BOOST_TEST(toml::get(alpha.at("ip")) == "10.0.0.1"); + BOOST_TEST(toml::get(alpha.at("dc")) == "eqdc10"); + + toml::table beta = toml::find(servers, "beta"); + BOOST_TEST(toml::get(beta.at("ip")) == "10.0.0.2"); + BOOST_TEST(toml::get(beta.at("dc")) == "eqdc10"); + BOOST_TEST(toml::get(beta.at("country")) == "\xE4\xB8\xAD\xE5\x9B\xBD"); + } + + const auto& clients = toml::find(data, "clients"); + { + toml::array clients_data = toml::find(clients, "data"); + std::vector expected_name{"gamma", "delta"}; + BOOST_CHECK(toml::get>(clients_data.at(0)) == expected_name); + + std::vector expected_number{1, 2}; + BOOST_CHECK(toml::get>(clients_data.at(1)) == expected_number); + + std::vector expected_hosts{"alpha", "omega"}; + BOOST_CHECK(toml::find>(clients, "hosts") == expected_hosts); + } + + std::vector products = + toml::find>(data, "products"); + { + BOOST_TEST(toml::get(products.at(0).at("name")) == + "Hammer"); + BOOST_TEST(toml::get(products.at(0).at("sku")) == + 738594937); + + BOOST_TEST(toml::get(products.at(1).at("name")) == + "Nail"); + BOOST_TEST(toml::get(products.at(1).at("sku")) == + 284758393); + BOOST_TEST(toml::get(products.at(1).at("color")) == + "gray"); + } +} + +BOOST_AUTO_TEST_CASE(test_fruit) +{ + const auto data = toml::parse(testinput("fruit.toml")); + const auto blah = toml::find(toml::find(data, "fruit"), "blah"); + BOOST_TEST(toml::find(blah.at(0), "name") == "apple"); + BOOST_TEST(toml::find(blah.at(1), "name") == "banana"); + { + const auto physical = toml::find(blah.at(0), "physical"); + BOOST_TEST(toml::find(physical, "color") == "red"); + BOOST_TEST(toml::find(physical, "shape") == "round"); + } + { + const auto physical = toml::find(blah.at(1), "physical"); + BOOST_TEST(toml::find(physical, "color") == "yellow"); + BOOST_TEST(toml::find(physical, "shape") == "bent"); + } +} + +BOOST_AUTO_TEST_CASE(test_hard_example) +{ + const auto data = toml::parse(testinput("hard_example.toml")); + const auto the = toml::find(data, "the"); + BOOST_TEST(toml::find(the, "test_string") == + "You'll hate me after this - #"); + + const auto hard = toml::find(the, "hard"); + const std::vector expected_the_hard_test_array{"] ", " # "}; + BOOST_CHECK(toml::find>(hard, "test_array") == + expected_the_hard_test_array); + const std::vector expected_the_hard_test_array2{ + "Test #11 ]proved that", "Experiment #9 was a success"}; + BOOST_CHECK(toml::find>(hard, "test_array2") == + expected_the_hard_test_array2); + BOOST_TEST(toml::find(hard, "another_test_string") == + " Same thing, but with a string #"); + BOOST_TEST(toml::find(hard, "harder_test_string") == + " And when \"'s are in the string, along with # \""); + + const auto bit = toml::find(hard, "bit#"); + BOOST_TEST(toml::find(bit, "what?") == + "You don't think some user won't do that?"); + const std::vector expected_multi_line_array{"]"}; + BOOST_CHECK(toml::find>(bit, "multi_line_array") == + expected_multi_line_array); +} +BOOST_AUTO_TEST_CASE(test_hard_example_comment) +{ + const auto data = toml::parse(testinput("hard_example.toml")); + const auto the = toml::find(data, "the"); + BOOST_TEST(toml::find(the, "test_string") == + "You'll hate me after this - #"); + + const auto hard = toml::find(the, "hard"); + const std::vector expected_the_hard_test_array{"] ", " # "}; + BOOST_CHECK(toml::find>(hard, "test_array") == + expected_the_hard_test_array); + const std::vector expected_the_hard_test_array2{ + "Test #11 ]proved that", "Experiment #9 was a success"}; + BOOST_CHECK(toml::find>(hard, "test_array2") == + expected_the_hard_test_array2); + BOOST_TEST(toml::find(hard, "another_test_string") == + " Same thing, but with a string #"); + BOOST_TEST(toml::find(hard, "harder_test_string") == + " And when \"'s are in the string, along with # \""); + + const auto bit = toml::find(hard, "bit#"); + BOOST_TEST(toml::find(bit, "what?") == + "You don't think some user won't do that?"); + const std::vector expected_multi_line_array{"]"}; + BOOST_CHECK(toml::find>(bit, "multi_line_array") == + expected_multi_line_array); +} + + +BOOST_AUTO_TEST_CASE(test_example_preserve_comment) +{ + const auto data = toml::parse(testinput("example.toml")); + + BOOST_TEST(toml::find(data, "title") == "TOML Example"); + const auto& owner = toml::find(data, "owner"); + { + BOOST_TEST(toml::find(owner, "name") == "Tom Preston-Werner"); + BOOST_TEST(toml::find(owner, "organization") == "GitHub"); + BOOST_TEST(toml::find(owner, "bio") == + "GitHub Cofounder & CEO\nLikes tater tots and beer."); + BOOST_TEST(toml::find(owner, "dob") == + toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0), toml::time_offset(0, 0))); + BOOST_TEST(toml::find(owner, "dob").comments().at(0) == + " First class dates? Why not?"); + } + + const auto& database = toml::find(data, "database"); + { + BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); + const std::vector expected_ports{8001, 8001, 8002}; + BOOST_CHECK(toml::find>(database, "ports") == expected_ports); + BOOST_TEST(toml::find(database, "connection_max") == 5000); + BOOST_TEST(toml::find(database, "enabled") == true); + } + + const auto& servers = toml::find(data, "servers"); + { + const auto& alpha = toml::find(servers, "alpha"); + BOOST_TEST(alpha.comments().at(0) == + " You can indent as you please. Tabs or spaces. TOML don't care."); + BOOST_TEST(toml::find(alpha, "ip") == "10.0.0.1"); + BOOST_TEST(toml::find(alpha, "dc") == "eqdc10"); + + const auto& beta = toml::find(servers, "beta"); + BOOST_TEST(toml::find(beta, "ip") == "10.0.0.2"); + BOOST_TEST(toml::find(beta, "dc") == "eqdc10"); + BOOST_TEST(toml::find(beta, "country") == + "\xE4\xB8\xAD\xE5\x9B\xBD"); + BOOST_TEST(toml::find(beta, "country").comments().at(0) == + " This should be parsed as UTF-8"); + } + + const auto& clients = toml::find(data, "clients"); + { + BOOST_TEST(toml::find(clients, "data").comments().at(0) == + " just an update to make sure parsers support it"); + + + toml::array clients_data = toml::find(clients, "data"); + std::vector expected_name{"gamma", "delta"}; + BOOST_CHECK(toml::get>(clients_data.at(0)) == + expected_name); + std::vector expected_number{1, 2}; + BOOST_CHECK(toml::get>(clients_data.at(1)) == + expected_number); + std::vector expected_hosts{"alpha", "omega"}; + BOOST_CHECK(toml::find>(clients, "hosts") == + expected_hosts); + + BOOST_TEST(toml::find(clients, "hosts").comments().at(0) == + " Line breaks are OK when inside arrays"); + } + + std::vector products = + toml::find>(data, "products"); + { + BOOST_TEST(toml::get(products.at(0).at("name")) == + "Hammer"); + BOOST_TEST(toml::get(products.at(0).at("sku")) == + 738594937); + + BOOST_TEST(toml::get(products.at(1).at("name")) == + "Nail"); + BOOST_TEST(toml::get(products.at(1).at("sku")) == + 284758393); + BOOST_TEST(toml::get(products.at(1).at("color")) == + "gray"); + } +} + +BOOST_AUTO_TEST_CASE(test_example_preserve_stdmap_stddeque) +{ + const auto data = toml::parse( + testinput("example.toml")); + + static_assert(std::is_same::type> + >::value, ""); + static_assert(std::is_same::type> + >::value, ""); + + BOOST_TEST(toml::find(data, "title") == "TOML Example"); + const auto& owner = toml::find(data, "owner"); + { + BOOST_TEST(toml::find(owner, "name") == "Tom Preston-Werner"); + BOOST_TEST(toml::find(owner, "organization") == "GitHub"); + BOOST_TEST(toml::find(owner, "bio") == + "GitHub Cofounder & CEO\nLikes tater tots and beer."); + BOOST_TEST(toml::find(owner, "dob") == + toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0), toml::time_offset(0, 0))); + BOOST_TEST(toml::find(owner, "dob").comments().at(0) == + " First class dates? Why not?"); + } + + const auto& database = toml::find(data, "database"); + { + BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); + const std::vector expected_ports{8001, 8001, 8002}; + BOOST_CHECK(toml::find>(database, "ports") == expected_ports); + BOOST_TEST(toml::find(database, "connection_max") == 5000); + BOOST_TEST(toml::find(database, "enabled") == true); + } + + const auto& servers = toml::find(data, "servers"); + { + const auto& alpha = toml::find(servers, "alpha"); + BOOST_TEST(alpha.comments().at(0) == + " You can indent as you please. Tabs or spaces. TOML don't care."); + BOOST_TEST(toml::find(alpha, "ip") == "10.0.0.1"); + BOOST_TEST(toml::find(alpha, "dc") == "eqdc10"); + + const auto& beta = toml::find(servers, "beta"); + BOOST_TEST(toml::find(beta, "ip") == "10.0.0.2"); + BOOST_TEST(toml::find(beta, "dc") == "eqdc10"); + BOOST_TEST(toml::find(beta, "country") == + "\xE4\xB8\xAD\xE5\x9B\xBD"); + BOOST_TEST(toml::find(beta, "country").comments().at(0) == + " This should be parsed as UTF-8"); + } + + const auto& clients = toml::find(data, "clients"); + { + BOOST_TEST(toml::find(clients, "data").comments().at(0) == + " just an update to make sure parsers support it"); + + + toml::array clients_data = toml::find(clients, "data"); + std::vector expected_name{"gamma", "delta"}; + BOOST_CHECK(toml::get>(clients_data.at(0)) == + expected_name); + std::vector expected_number{1, 2}; + BOOST_CHECK(toml::get>(clients_data.at(1)) == + expected_number); + std::vector expected_hosts{"alpha", "omega"}; + BOOST_CHECK(toml::find>(clients, "hosts") == + expected_hosts); + + BOOST_TEST(toml::find(clients, "hosts").comments().at(0) == + " Line breaks are OK when inside arrays"); + } + + std::vector products = + toml::find>(data, "products"); + { + BOOST_TEST(toml::get(products.at(0).at("name")) == + "Hammer"); + BOOST_TEST(toml::get(products.at(0).at("sku")) == + 738594937); + + BOOST_TEST(toml::get(products.at(1).at("name")) == + "Nail"); + BOOST_TEST(toml::get(products.at(1).at("sku")) == + 284758393); + BOOST_TEST(toml::get(products.at(1).at("color")) == + "gray"); + } +} + +// --------------------------------------------------------------------------- +// after here, the test codes generate the content of a file. + +BOOST_AUTO_TEST_CASE(test_file_with_BOM) +{ + { + const std::string table( + "\xEF\xBB\xBF" // BOM + "key = \"value\"\n" + "[table]\n" + "key = \"value\"\n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, "test_file_with_BOM.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "\xEF\xBB\xBF" // BOM + "key = \"value\"\n" + "[table]\n" + "key = \"value\"\n" + ); + { + std::ofstream ofs("tmp.toml"); + ofs << table; + } + const auto data = toml::parse("tmp.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "\xEF\xBB\xBF" // BOM + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\"\r\n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, "test_file_with_BOM_CRLF.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "\xEF\xBB\xBF" // BOM + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\"\r\n" + ); + { + // with text-mode, "\n" is converted to "\r\n" and the resulting + // value will be "\r\r\n". To avoid the additional "\r", use binary + // mode. + std::ofstream ofs("tmp.toml", std::ios_base::binary); + ofs.write(table.data(), static_cast(table.size())); + } + const auto data = toml::parse("tmp.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } +} + +BOOST_AUTO_TEST_CASE(test_file_without_newline_at_the_end_of_file) +{ + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\"" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_file_without_newline_at_the_end_of_file.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\"" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_file_without_newline_at_the_end_of_file_CRLF.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\" # comment" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_file_without_newline_at_the_end_of_file_comment.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\" # comment" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_file_without_newline_at_the_end_of_file_comment.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\" \t" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_file_without_newline_at_the_end_of_file_ws.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\" \t" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_file_without_newline_at_the_end_of_file_ws.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } +} + + +BOOST_AUTO_TEST_CASE(test_files_end_with_comment) +{ + // comment w/o newline + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\"\n" + "# comment" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_comment.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\"\n" + "# comment\n" + "# one more comment" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_comment.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + + // comment w/ newline + + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\"\n" + "# comment\n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_comment.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\"\n" + "# comment\n" + "# one more comment\n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_comment.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + + // CRLF version + + { + const std::string table( + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\"\r\n" + "# comment" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_comment.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\"\r\n" + "# comment\r\n" + "# one more comment" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_comment.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\"\r\n" + "# comment\r\n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_comment.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\"\r\n" + "# comment\r\n" + "# one more comment\r\n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_comment.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } +} + + +BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) +{ + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\"\n" + "\n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_newline.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\"\n" + "\n" + "\n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_newline.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + + // with whitespaces + + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\"\n" + " \n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_newline.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\"\n" + " \n" + " \n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_newline.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\"\n" + "\n" + " \n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_newline.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\"\n" + " \n" + "\n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_newline.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + + // with whitespaces but no newline + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\"\n" + " " + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_newline.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + + // without newline + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\"\n" + "a = 0" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_newline.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + + + // CRLF + + { + const std::string table( + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\"\r\n" + "\r\n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_newline.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\"\r\n" + "\r\n" + "\r\n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_newline.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + + // with whitespaces + + { + const std::string table( + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\"\r\n" + " \r\n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_newline.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\"\r\n" + "\r\n" + " \r\n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_newline.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\"\r\n" + " \r\n" + "\r\n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_newline.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\"\r\n" + " \r\n" + " \r\n" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_newline.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + { + const std::string table( + "key = \"value\"\r\n" + "[table]\r\n" + "key = \"value\"\r\n" + " " + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_with_newline.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } +} + +BOOST_AUTO_TEST_CASE(test_file_ends_without_lf) +{ + { + const std::string table( + "key = \"value\"\n" + "[table]\n" + "key = \"value\"" + ); + std::istringstream iss(table); + const auto data = toml::parse(iss, + "test_files_end_without_lf.toml"); + + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } +} + +BOOST_AUTO_TEST_CASE(test_parse_function_compiles) +{ + using result_type = decltype(toml::parse("string literal")); + (void) [](const char* that) -> result_type { return toml::parse(that); }; + (void) [](char* that) -> result_type { return toml::parse(that); }; + (void) [](const std::string& that) -> result_type { return toml::parse(that); }; + (void) [](std::string& that) -> result_type { return toml::parse(that); }; + (void) [](std::string&& that) -> result_type { return toml::parse(that); }; +#ifdef TOML11_HAS_STD_FILESYSTEM + (void) [](const std::filesystem::path& that) -> result_type { return toml::parse(that); }; + (void) [](std::filesystem::path& that) -> result_type { return toml::parse(that); }; + (void) [](std::filesystem::path&& that) -> result_type { return toml::parse(that); }; +#endif + (void) [](std::FILE* that) -> result_type { return toml::parse(that, "mandatory.toml"); }; +} + +BOOST_AUTO_TEST_CASE(test_parse_nonexistent_file) +{ + BOOST_CHECK_THROW(toml::parse("nonexistent.toml"), std::ios_base::failure); +} diff --git a/external/toml11/tests/test_parse_floating.cpp b/external/toml11/tests/test_parse_floating.cpp new file mode 100644 index 0000000..5c05bab --- /dev/null +++ b/external/toml11/tests/test_parse_floating.cpp @@ -0,0 +1,181 @@ +#include + +#include "unit_test.hpp" +#include "test_parse_aux.hpp" + +#include + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_fractional) +{ + TOML11_TEST_PARSE_EQUAL(parse_floating, "1.0", 1.0); + TOML11_TEST_PARSE_EQUAL(parse_floating, "0.1", 0.1); + TOML11_TEST_PARSE_EQUAL(parse_floating, "0.001", 0.001); + TOML11_TEST_PARSE_EQUAL(parse_floating, "0.100", 0.1); + TOML11_TEST_PARSE_EQUAL(parse_floating, "+3.14", 3.14); + TOML11_TEST_PARSE_EQUAL(parse_floating, "-3.14", -3.14); + TOML11_TEST_PARSE_EQUAL(parse_floating, "3.1415_9265_3589", 3.141592653589); + TOML11_TEST_PARSE_EQUAL(parse_floating, "+3.1415_9265_3589", 3.141592653589); + TOML11_TEST_PARSE_EQUAL(parse_floating, "-3.1415_9265_3589", -3.141592653589); + TOML11_TEST_PARSE_EQUAL(parse_floating, "123_456.789", 123456.789); + TOML11_TEST_PARSE_EQUAL(parse_floating, "+123_456.789", 123456.789); + TOML11_TEST_PARSE_EQUAL(parse_floating, "-123_456.789", -123456.789); + TOML11_TEST_PARSE_EQUAL(parse_floating, "+0.0", 0.0); + TOML11_TEST_PARSE_EQUAL(parse_floating, "-0.0", -0.0); +} + +BOOST_AUTO_TEST_CASE(test_fractional_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1.0", value( 1.0)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0.1", value( 0.1)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0.001", value( 0.001)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0.100", value( 0.1)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+3.14", value( 3.14)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-3.14", value(-3.14)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "3.1415_9265_3589", value( 3.141592653589)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+3.1415_9265_3589", value( 3.141592653589)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-3.1415_9265_3589", value(-3.141592653589)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "123_456.789", value( 123456.789)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+123_456.789", value( 123456.789)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-123_456.789", value(-123456.789)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+0.0", value( 0.0)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-0.0", value(-0.0)); +} + +BOOST_AUTO_TEST_CASE(test_exponential) +{ + TOML11_TEST_PARSE_EQUAL(parse_floating, "1e10", 1e10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "1e+10", 1e10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "1e-10", 1e-10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "+1e10", 1e10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "+1e+10", 1e10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "+1e-10", 1e-10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "-1e10", -1e10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "-1e+10", -1e10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "-1e-10", -1e-10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "123e-10", 123e-10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "1E10", 1e10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "1E+10", 1e10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "1E-10", 1e-10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "123E-10", 123e-10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "1_2_3E-10", 123e-10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "1_2_3E-1_0", 123e-10); + TOML11_TEST_PARSE_EQUAL(parse_floating, "+0e0", 0.0); + TOML11_TEST_PARSE_EQUAL(parse_floating, "-0e0", -0.0); + +#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES + BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part"); + // toml-lang/toml master permits leading 0s in exp part (unreleased) + TOML11_TEST_PARSE_EQUAL(parse_floating, "1_2_3E-01", 123e-1); + TOML11_TEST_PARSE_EQUAL(parse_floating, "1_2_3E-0_1", 123e-1); +#endif +} + +BOOST_AUTO_TEST_CASE(test_exponential_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1e10", value(1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1e+10", value(1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1e-10", value(1e-10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1e10", value(1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1e+10", value(1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1e-10", value(1e-10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1e10", value(-1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1e+10", value(-1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1e-10", value(-1e-10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "123e-10", value(123e-10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1E10", value(1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1E+10", value(1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1E-10", value(1e-10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "123E-10", value(123e-10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1_2_3E-10", value(123e-10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1_2_3E-1_0", value(123e-10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+0e0", value( 0.0)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-0e0", value(-0.0)); + +#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES + BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part"); + // toml-lang/toml master permits leading 0s in exp part (unreleased) + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1_2_3E-01", value(123e-1)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1_2_3E-0_1", value(123e-1)); +#endif +} +BOOST_AUTO_TEST_CASE(test_fe) +{ + TOML11_TEST_PARSE_EQUAL(parse_floating, "6.02e23", 6.02e23); + TOML11_TEST_PARSE_EQUAL(parse_floating, "6.02e+23", 6.02e23); + TOML11_TEST_PARSE_EQUAL(parse_floating, "1.112_650_06e-17", 1.11265006e-17); +} +BOOST_AUTO_TEST_CASE(test_fe_vaule) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "6.02e23", value(6.02e23)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "6.02e+23", value(6.02e23)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1.112_650_06e-17", value(1.11265006e-17)); + +#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES + BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part"); + // toml-lang/toml master permits leading 0s in exp part (unreleased) + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "3.141_5e-01", value(3.1415e-1)); +#endif +} + +BOOST_AUTO_TEST_CASE(test_inf) +{ + { + const std::string token("inf"); + toml::detail::location loc("test", token); + const auto r = parse_floating(loc); + BOOST_CHECK(r.is_ok()); + BOOST_CHECK(std::isinf(r.unwrap().first)); + BOOST_CHECK(r.unwrap().first > 0.0); + } + { + const std::string token("+inf"); + toml::detail::location loc("test", token); + const auto r = parse_floating(loc); + BOOST_CHECK(r.is_ok()); + BOOST_CHECK(std::isinf(r.unwrap().first)); + BOOST_CHECK(r.unwrap().first > 0.0); + } + { + const std::string token("-inf"); + toml::detail::location loc("test", token); + const auto r = parse_floating(loc); + BOOST_CHECK(r.is_ok()); + BOOST_CHECK(std::isinf(r.unwrap().first)); + BOOST_CHECK(r.unwrap().first < 0.0); + } +} + +BOOST_AUTO_TEST_CASE(test_nan) +{ + { + const std::string token("nan"); + toml::detail::location loc("test", token); + const auto r = parse_floating(loc); + BOOST_CHECK(r.is_ok()); + BOOST_CHECK(std::isnan(r.unwrap().first)); + } + { + const std::string token("+nan"); + toml::detail::location loc("test", token); + const auto r = parse_floating(loc); + BOOST_CHECK(r.is_ok()); + BOOST_CHECK(std::isnan(r.unwrap().first)); + } + { + const std::string token("-nan"); + toml::detail::location loc("test", token); + const auto r = parse_floating(loc); + BOOST_CHECK(r.is_ok()); + BOOST_CHECK(std::isnan(r.unwrap().first)); + } +} + +BOOST_AUTO_TEST_CASE(test_overflow) +{ + std::istringstream float_overflow (std::string("float-overflow = 1.0e+1024")); + BOOST_CHECK_THROW(toml::parse(float_overflow ), toml::syntax_error); + // istringstream >> float does not set failbit in case of underflow. +} diff --git a/external/toml11/tests/test_parse_inline_table.cpp b/external/toml11/tests/test_parse_inline_table.cpp new file mode 100644 index 0000000..a11767c --- /dev/null +++ b/external/toml11/tests/test_parse_inline_table.cpp @@ -0,0 +1,59 @@ +#include + +#include "unit_test.hpp" +#include "test_parse_aux.hpp" + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_inline_table) +{ + TOML11_TEST_PARSE_EQUAL_VAT(parse_inline_table, "{}", table()); + { + table t; + t["foo"] = toml::value(42); + t["bar"] = toml::value("baz"); + TOML11_TEST_PARSE_EQUAL_VAT(parse_inline_table, "{foo = 42, bar = \"baz\"}", t); + } + { + table t; + table t_sub; + t_sub["name"] = toml::value("pug"); + t["type"] = toml::value(t_sub); + TOML11_TEST_PARSE_EQUAL_VAT(parse_inline_table, "{type.name = \"pug\"}", t); + } +} + +BOOST_AUTO_TEST_CASE(test_inline_table_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "{}", value(table())); + { + table t; + t["foo"] = toml::value(42); + t["bar"] = toml::value("baz"); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "{foo = 42, bar = \"baz\"}", value(t)); + } + { + table t; + table t_sub; + t_sub["name"] = toml::value("pug"); + t["type"] = toml::value(t_sub); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "{type.name = \"pug\"}", value(t)); + } +} + +BOOST_AUTO_TEST_CASE(test_inline_table_immutability) +{ + { + std::istringstream stream(std::string( + "a = {b = 1}\n" + "a.c = 2\n")); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); + } + { + std::istringstream stream(std::string( + "a = {b = {c = 1}}\n" + "a.b.d = 2\n")); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); + } +} diff --git a/external/toml11/tests/test_parse_integer.cpp b/external/toml11/tests/test_parse_integer.cpp new file mode 100644 index 0000000..4a86226 --- /dev/null +++ b/external/toml11/tests/test_parse_integer.cpp @@ -0,0 +1,116 @@ +#include + +#include "unit_test.hpp" +#include "test_parse_aux.hpp" + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_decimal) +{ + TOML11_TEST_PARSE_EQUAL(parse_integer, "1234", 1234); + TOML11_TEST_PARSE_EQUAL(parse_integer, "+1234", 1234); + TOML11_TEST_PARSE_EQUAL(parse_integer, "-1234", -1234); + TOML11_TEST_PARSE_EQUAL(parse_integer, "0", 0); + TOML11_TEST_PARSE_EQUAL(parse_integer, "1_2_3_4", 1234); + TOML11_TEST_PARSE_EQUAL(parse_integer, "+1_2_3_4", +1234); + TOML11_TEST_PARSE_EQUAL(parse_integer, "-1_2_3_4", -1234); + TOML11_TEST_PARSE_EQUAL(parse_integer, "123_456_789", 123456789); +} + +BOOST_AUTO_TEST_CASE(test_decimal_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1234", toml::value( 1234)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1234", toml::value( 1234)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1234", toml::value( -1234)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0", toml::value( 0)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1_2_3_4", toml::value( 1234)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1_2_3_4", toml::value( +1234)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1_2_3_4", toml::value( -1234)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "123_456_789", toml::value(123456789)); +} + +BOOST_AUTO_TEST_CASE(test_hex) +{ + TOML11_TEST_PARSE_EQUAL(parse_integer, "0xDEADBEEF", 0xDEADBEEF); + TOML11_TEST_PARSE_EQUAL(parse_integer, "0xdeadbeef", 0xDEADBEEF); + TOML11_TEST_PARSE_EQUAL(parse_integer, "0xDEADbeef", 0xDEADBEEF); + TOML11_TEST_PARSE_EQUAL(parse_integer, "0xDEAD_BEEF", 0xDEADBEEF); + TOML11_TEST_PARSE_EQUAL(parse_integer, "0xdead_beef", 0xDEADBEEF); + TOML11_TEST_PARSE_EQUAL(parse_integer, "0xdead_BEEF", 0xDEADBEEF); + TOML11_TEST_PARSE_EQUAL(parse_integer, "0xFF", 0xFF); + TOML11_TEST_PARSE_EQUAL(parse_integer, "0x00FF", 0xFF); + TOML11_TEST_PARSE_EQUAL(parse_integer, "0x0000FF", 0xFF); +} + +BOOST_AUTO_TEST_CASE(test_hex_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xDEADBEEF", value(0xDEADBEEF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xdeadbeef", value(0xDEADBEEF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xDEADbeef", value(0xDEADBEEF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xDEAD_BEEF", value(0xDEADBEEF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xdead_beef", value(0xDEADBEEF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xdead_BEEF", value(0xDEADBEEF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xFF", value(0xFF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0x00FF", value(0xFF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0x0000FF", value(0xFF)); +} + +BOOST_AUTO_TEST_CASE(test_oct) +{ + TOML11_TEST_PARSE_EQUAL(parse_integer, "0o777", 64*7+8*7+7); + TOML11_TEST_PARSE_EQUAL(parse_integer, "0o7_7_7", 64*7+8*7+7); + TOML11_TEST_PARSE_EQUAL(parse_integer, "0o007", 7); +} + +BOOST_AUTO_TEST_CASE(test_oct_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0o777", value(64*7+8*7+7)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0o7_7_7", value(64*7+8*7+7)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0o007", value(7)); +} + +BOOST_AUTO_TEST_CASE(test_bin) +{ + TOML11_TEST_PARSE_EQUAL(parse_integer, "0b10000", 16); + TOML11_TEST_PARSE_EQUAL(parse_integer, "0b010000", 16); + TOML11_TEST_PARSE_EQUAL(parse_integer, "0b01_00_00", 16); + TOML11_TEST_PARSE_EQUAL(parse_integer, "0b111111", 63); +} + +BOOST_AUTO_TEST_CASE(test_bin_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b10000", value(16)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b010000", value(16)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b01_00_00", value(16)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b111111", value(63)); + + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "0b1000_1000_1000_1000_1000_1000_1000_1000_1000_1000_1000_1000_1000_1000_1000", + // 1 0 0 0 + // 0 C 8 4 + value(0x0888888888888888)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "0b01111111_11111111_11111111_11111111_11111111_11111111_11111111_11111111", + // 1 0 0 0 + // 0 C 8 4 + value(0x7FFFFFFFFFFFFFFF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "0b00000000_01111111_11111111_11111111_11111111_11111111_11111111_11111111_11111111", + // 1 0 0 0 + // 0 C 8 4 + value(0x7FFFFFFFFFFFFFFF)); +} + +BOOST_AUTO_TEST_CASE(test_integer_overflow) +{ + std::istringstream dec_overflow(std::string("dec-overflow = 9223372036854775808")); + std::istringstream hex_overflow(std::string("hex-overflow = 0x1_00000000_00000000")); + std::istringstream oct_overflow(std::string("oct-overflow = 0o1_000_000_000_000_000_000_000")); + // 64 56 48 40 32 24 16 8 + std::istringstream bin_overflow(std::string("bin-overflow = 0b10000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000")); + BOOST_CHECK_THROW(toml::parse(dec_overflow), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(hex_overflow), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(oct_overflow), toml::syntax_error); + BOOST_CHECK_THROW(toml::parse(bin_overflow), toml::syntax_error); +} diff --git a/external/toml11/tests/test_parse_key.cpp b/external/toml11/tests/test_parse_key.cpp new file mode 100644 index 0000000..3af0eaa --- /dev/null +++ b/external/toml11/tests/test_parse_key.cpp @@ -0,0 +1,58 @@ +#include + +#include "unit_test.hpp" +#include "test_parse_aux.hpp" + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_bare_key) +{ + TOML11_TEST_PARSE_EQUAL(parse_key, "barekey", std::vector(1, "barekey")); + TOML11_TEST_PARSE_EQUAL(parse_key, "bare-key", std::vector(1, "bare-key")); + TOML11_TEST_PARSE_EQUAL(parse_key, "bare_key", std::vector(1, "bare_key")); + TOML11_TEST_PARSE_EQUAL(parse_key, "1234", std::vector(1, "1234")); +} + +BOOST_AUTO_TEST_CASE(test_quoted_key) +{ + TOML11_TEST_PARSE_EQUAL(parse_key, "\"127.0.0.1\"", std::vector(1, "127.0.0.1" )); + TOML11_TEST_PARSE_EQUAL(parse_key, "\"character encoding\"", std::vector(1, "character encoding")); +#if defined(_MSC_VER) || defined(__INTEL_COMPILER) + TOML11_TEST_PARSE_EQUAL(parse_key, "\"\xCA\x8E\xC7\x9D\xCA\x9E\"", std::vector(1, "\xCA\x8E\xC7\x9D\xCA\x9E")); +#else + TOML11_TEST_PARSE_EQUAL(parse_key, "\"ʎǝʞ\"", std::vector(1, "ʎǝʞ" )); +#endif + TOML11_TEST_PARSE_EQUAL(parse_key, "'key2'", std::vector(1, "key2" )); + TOML11_TEST_PARSE_EQUAL(parse_key, "'quoted \"value\"'", std::vector(1, "quoted \"value\"" )); +} + +BOOST_AUTO_TEST_CASE(test_dotted_key) +{ + { + std::vector keys(2); + keys[0] = "physical"; + keys[1] = "color"; + TOML11_TEST_PARSE_EQUAL(parse_key, "physical.color", keys); + } + { + std::vector keys(2); + keys[0] = "physical"; + keys[1] = "shape"; + TOML11_TEST_PARSE_EQUAL(parse_key, "physical.shape", keys); + } + { + std::vector keys(4); + keys[0] = "x"; + keys[1] = "y"; + keys[2] = "z"; + keys[3] = "w"; + TOML11_TEST_PARSE_EQUAL(parse_key, "x.y.z.w", keys); + } + { + std::vector keys(2); + keys[0] = "site"; + keys[1] = "google.com"; + TOML11_TEST_PARSE_EQUAL(parse_key, "site.\"google.com\"", keys); + } +} diff --git a/external/toml11/tests/test_parse_string.cpp b/external/toml11/tests/test_parse_string.cpp new file mode 100644 index 0000000..bf381e3 --- /dev/null +++ b/external/toml11/tests/test_parse_string.cpp @@ -0,0 +1,245 @@ +#include + +#include "unit_test.hpp" +#include "test_parse_aux.hpp" + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_string) +{ + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"The quick brown fox jumps over the lazy dog\"", + string("The quick brown fox jumps over the lazy dog", string_t::basic)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "\'The quick brown fox jumps over the lazy dog\'", + string("The quick brown fox jumps over the lazy dog", string_t::literal)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"\"\"The quick brown fox \\\njumps over the lazy dog\"\"\"", + string("The quick brown fox jumps over the lazy dog", string_t::basic)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "'''The quick brown fox \njumps over the lazy dog'''", + string("The quick brown fox \njumps over the lazy dog", string_t::literal)); +} + +BOOST_AUTO_TEST_CASE(test_string_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\"The quick brown fox jumps over the lazy dog\"", + toml::value("The quick brown fox jumps over the lazy dog", string_t::basic)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\'The quick brown fox jumps over the lazy dog\'", + toml::value("The quick brown fox jumps over the lazy dog", string_t::literal)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\"\"\"The quick brown fox \\\njumps over the lazy dog\"\"\"", + toml::value("The quick brown fox jumps over the lazy dog", string_t::basic)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "'''The quick brown fox \njumps over the lazy dog'''", + toml::value("The quick brown fox \njumps over the lazy dog", string_t::literal)); +} + + +BOOST_AUTO_TEST_CASE(test_basic_string) +{ + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"GitHub Cofounder & CEO\\nLikes tater tots and beer.\"", + string("GitHub Cofounder & CEO\nLikes tater tots and beer.", string_t::basic)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"192.168.1.1\"", + string("192.168.1.1", string_t::basic)); + +#if defined(_MSC_VER) || defined(__INTEL_COMPILER) + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"\xE4\xB8\xAD\xE5\x9B\xBD\"", + string("\xE4\xB8\xAD\xE5\x9B\xBD", string_t::basic)); +#else + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"中国\"", + string("中国", string_t::basic)); +#endif + + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"You'll hate me after this - #\"", + string("You'll hate me after this - #", string_t::basic)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "\" And when \\\"'s are in the along with # \\\"\"", + string(" And when \"'s are in the along with # \"", string_t::basic)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"Here are fifteen apostrophes: '''''''''''''''\"", + string("Here are fifteen apostrophes: '''''''''''''''", string_t::basic)); +} + +BOOST_AUTO_TEST_CASE(test_basic_string_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\"GitHub Cofounder & CEO\\nLikes tater tots and beer.\"", + value("GitHub Cofounder & CEO\nLikes tater tots and beer.", string_t::basic)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\"192.168.1.1\"", + value("192.168.1.1", string_t::basic)); +#if defined(_MSC_VER) || defined(__INTEL_COMPILER) + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\"\xE4\xB8\xAD\xE5\x9B\xBD\"", + value("\xE4\xB8\xAD\xE5\x9B\xBD", string_t::basic)); +#else + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\"中国\"", + value("中国", string_t::basic)); +#endif + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\"You'll hate me after this - #\"", + value("You'll hate me after this - #", string_t::basic)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\" And when \\\"'s are in the along with # \\\"\"", + value(" And when \"'s are in the along with # \"", string_t::basic)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\"Here are fifteen apostrophes: '''''''''''''''\"", + value("Here are fifteen apostrophes: '''''''''''''''", string_t::basic)); +} + +BOOST_AUTO_TEST_CASE(test_ml_basic_string) +{ + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"\"\"\nThe quick brown \\\n\n fox jumps over \\\n the lazy dog.\"\"\"", + string("The quick brown fox jumps over the lazy dog.", string_t::basic)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"\"\"\\\n The quick brown \\\n\n fox jumps over \\\n the lazy dog.\\\n \"\"\"", + string("The quick brown fox jumps over the lazy dog.", string_t::basic)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"\"\"Here are two quotation marks: \"\". Simple enough.\"\"\"", + string("Here are two quotation marks: \"\". Simple enough.", string_t::basic)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"\"\"Here are three quotation marks: \"\"\\\".\"\"\"", + string("Here are three quotation marks: \"\"\".", string_t::basic)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"\"\"Here are fifteen quotation marks: \"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\".\"\"\"", + string("Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".", string_t::basic)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"\"\"\"This,\" she said, \"is just a pointless statement.\"\"\"\"", + string("\"This,\" she said, \"is just a pointless statement.\"", string_t::basic)); +} + +BOOST_AUTO_TEST_CASE(test_ml_basic_string_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\"\"\"\nThe quick brown \\\n\n fox jumps over \\\n the lazy dog.\"\"\"", + value("The quick brown fox jumps over the lazy dog.", string_t::basic)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\"\"\"\\\n The quick brown \\\n\n fox jumps over \\\n the lazy dog.\\\n \"\"\"", + value("The quick brown fox jumps over the lazy dog.", string_t::basic)); + + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\"\"\"Here are two quotation marks: \"\". Simple enough.\"\"\"", + value("Here are two quotation marks: \"\". Simple enough.", string_t::basic)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\"\"\"Here are three quotation marks: \"\"\\\".\"\"\"", + value("Here are three quotation marks: \"\"\".", string_t::basic)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\"\"\"Here are fifteen quotation marks: \"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\".\"\"\"", + value("Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".", string_t::basic)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\"\"\"\"This,\" she said, \"is just a pointless statement.\"\"\"\"", + value("\"This,\" she said, \"is just a pointless statement.\"", string_t::basic)); +} + +BOOST_AUTO_TEST_CASE(test_literal_string) +{ + TOML11_TEST_PARSE_EQUAL(parse_string, + "'C:\\Users\\nodejs\\templates'", + string("C:\\Users\\nodejs\\templates", string_t::literal)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "'\\\\ServerX\\admin$\\system32\\'", + string("\\\\ServerX\\admin$\\system32\\", string_t::literal)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "'Tom \"Dubs\" Preston-Werner'", + string("Tom \"Dubs\" Preston-Werner", string_t::literal)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "'<\\i\\c*\\s*>'", + string("<\\i\\c*\\s*>", string_t::literal)); +} + +BOOST_AUTO_TEST_CASE(test_literal_string_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "'C:\\Users\\nodejs\\templates'", + value("C:\\Users\\nodejs\\templates", string_t::literal)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "'\\\\ServerX\\admin$\\system32\\'", + value("\\\\ServerX\\admin$\\system32\\", string_t::literal)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "'Tom \"Dubs\" Preston-Werner'", + value("Tom \"Dubs\" Preston-Werner", string_t::literal)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "'<\\i\\c*\\s*>'", + value("<\\i\\c*\\s*>", string_t::literal)); +} + +BOOST_AUTO_TEST_CASE(test_ml_literal_string) +{ + TOML11_TEST_PARSE_EQUAL(parse_string, + "'''I [dw]on't need \\d{2} apples'''", + string("I [dw]on't need \\d{2} apples", string_t::literal)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "'''\nThe first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n'''", + string("The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n", string_t::literal)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "''''That's still pointless', she said.'''", + string("'That's still pointless', she said.", string_t::literal)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "'''Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".'''", + string("Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".", string_t::literal)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "''''This,' she said, 'is just a pointless statement.''''", + string("'This,' she said, 'is just a pointless statement.'", string_t::literal)); +} + +BOOST_AUTO_TEST_CASE(test_ml_literal_string_value) +{ + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "'''I [dw]on't need \\d{2} apples'''", + value("I [dw]on't need \\d{2} apples", string_t::literal)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "'''\nThe first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n'''", + value("The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n", string_t::literal)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "''''That's still pointless', she said.'''", + value("'That's still pointless', she said.", string_t::literal)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "'''Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".'''", + value("Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".", string_t::literal)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "''''This,' she said, 'is just a pointless statement.''''", + value("'This,' she said, 'is just a pointless statement.'", string_t::literal)); +} + +BOOST_AUTO_TEST_CASE(test_simple_excape_sequences) +{ + TOML11_TEST_PARSE_EQUAL(parse_string, + R"("\"\\\b\f\n\r\t")", + string("\"\\\b\f\n\r\t", string_t::basic)); +#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES + TOML11_TEST_PARSE_EQUAL(parse_string, + R"("\e")", + string("\x1b", string_t::basic)); +#endif +} + + +BOOST_AUTO_TEST_CASE(test_unicode_escape_sequence) +{ +#if defined(_MSC_VER) || defined(__INTEL_COMPILER) + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"\\u03B1\\u03B2\\u03B3\"", + string("\xCE\xB1\xCE\xB2\xCE\xB3", string_t::basic)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"\\U0001D7AA\"", + string("\xF0\x9D\x9E\xAA", string_t::basic)); +#else + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"\\u03B1\\u03B2\\u03B3\"", + string("αβγ", string_t::basic)); + TOML11_TEST_PARSE_EQUAL(parse_string, + "\"\\U0001D7AA\"", + string("𝞪", string_t::basic)); +#endif +} diff --git a/external/toml11/tests/test_parse_table.cpp b/external/toml11/tests/test_parse_table.cpp new file mode 100644 index 0000000..0fd54c7 --- /dev/null +++ b/external/toml11/tests/test_parse_table.cpp @@ -0,0 +1,45 @@ +#include +#include + +#include "unit_test.hpp" +#include "test_parse_aux.hpp" + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_normal_table) +{ + std::string table( + "key1 = \"value\"\n" + "key2 = 42\n" + "key3 = 3.14\n" + ); + location loc("test", table); + + const auto result = toml::detail::parse_ml_table(loc); + BOOST_TEST(result.is_ok()); + const auto data = result.unwrap(); + + BOOST_TEST(toml::get(data.at("key1")) == "value"); + BOOST_TEST(toml::get(data.at("key2")) == 42); + BOOST_TEST(toml::get(data.at("key3")) == 3.14); +} + +BOOST_AUTO_TEST_CASE(test_nested_table) +{ + std::string table( + "a.b = \"value\"\n" + "a.c.d = 42\n" + ); + location loc("test", table); + + const auto result = toml::detail::parse_ml_table(loc); + BOOST_TEST(result.is_ok()); + const auto data = result.unwrap(); + + const auto a = toml::get(data.at("a")); + const auto c = toml::get(a.at("c")); + + BOOST_TEST(toml::get(a.at("b")) == "value"); + BOOST_TEST(toml::get(c.at("d")) == 42); +} diff --git a/external/toml11/tests/test_parse_table_key.cpp b/external/toml11/tests/test_parse_table_key.cpp new file mode 100644 index 0000000..a921c96 --- /dev/null +++ b/external/toml11/tests/test_parse_table_key.cpp @@ -0,0 +1,112 @@ +#include + +#include "unit_test.hpp" +#include "test_parse_aux.hpp" + +using namespace toml; +using namespace detail; + +BOOST_AUTO_TEST_CASE(test_table_bare_key) +{ + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[barekey]", std::vector(1, "barekey")); + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[bare-key]", std::vector(1, "bare-key")); + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[bare_key]", std::vector(1, "bare_key")); + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[1234]", std::vector(1, "1234")); +} + +BOOST_AUTO_TEST_CASE(test_table_quoted_key) +{ + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[\"127.0.0.1\"]", std::vector(1, "127.0.0.1" )); + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[\"character encoding\"]", std::vector(1, "character encoding")); + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[\"ʎǝʞ\"]", std::vector(1, "ʎǝʞ" )); + TOML11_TEST_PARSE_EQUAL(parse_table_key, "['key2']", std::vector(1, "key2" )); + TOML11_TEST_PARSE_EQUAL(parse_table_key, "['quoted \"value\"']", std::vector(1, "quoted \"value\"" )); +} + +BOOST_AUTO_TEST_CASE(test_table_dotted_key) +{ + { + std::vector keys(2); + keys[0] = "physical"; + keys[1] = "color"; + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[physical.color]", keys); + } + { + std::vector keys(2); + keys[0] = "physical"; + keys[1] = "shape"; + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[physical.shape]", keys); + } + { + std::vector keys(4); + keys[0] = "x"; + keys[1] = "y"; + keys[2] = "z"; + keys[3] = "w"; + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[x.y.z.w]", keys); + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[x . y . z . w]", keys); + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[x. y .z. w]", keys); + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[x .y. z .w]", keys); + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[ x. y .z . w ]", keys); + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[ x . y . z . w ]", keys); + } + { + std::vector keys(2); + keys[0] = "site"; + keys[1] = "google.com"; + TOML11_TEST_PARSE_EQUAL(parse_table_key, "[site.\"google.com\"]", keys); + } +} + +BOOST_AUTO_TEST_CASE(test_array_of_table_bare_key) +{ + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[barekey]]", std::vector(1, "barekey")); + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[bare-key]]", std::vector(1, "bare-key")); + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[bare_key]]", std::vector(1, "bare_key")); + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[1234]]", std::vector(1, "1234")); +} + +BOOST_AUTO_TEST_CASE(test_array_of_table_quoted_key) +{ + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[\"127.0.0.1\"]]", std::vector(1, "127.0.0.1" )); + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[\"character encoding\"]]", std::vector(1, "character encoding")); + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[\"ʎǝʞ\"]]", std::vector(1, "ʎǝʞ" )); + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[['key2']]", std::vector(1, "key2" )); + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[['quoted \"value\"']]", std::vector(1, "quoted \"value\"" )); +} + +BOOST_AUTO_TEST_CASE(test_array_of_table_dotted_key) +{ + { + std::vector keys(2); + keys[0] = "physical"; + keys[1] = "color"; + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[physical.color]]", keys); + } + { + std::vector keys(2); + keys[0] = "physical"; + keys[1] = "shape"; + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[physical.shape]]", keys); + } + { + std::vector keys(4); + keys[0] = "x"; + keys[1] = "y"; + keys[2] = "z"; + keys[3] = "w"; + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[x.y.z.w]]", keys); + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[x . y . z . w]]", keys); + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[x. y .z. w]]", keys); + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[x .y. z .w]]", keys); + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[ x. y .z . w ]]", keys); + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[ x . y . z . w ]]", keys); + + } + { + std::vector keys(2); + keys[0] = "site"; + keys[1] = "google.com"; + TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[site.\"google.com\"]]", keys); + } +} diff --git a/external/toml11/tests/test_parse_unicode.cpp b/external/toml11/tests/test_parse_unicode.cpp new file mode 100644 index 0000000..8bc4253 --- /dev/null +++ b/external/toml11/tests/test_parse_unicode.cpp @@ -0,0 +1,37 @@ +#include + +#include "unit_test.hpp" + +#include +#include + +BOOST_AUTO_TEST_CASE(test_hard_example_unicode) +{ + const auto data = toml::parse(testinput("hard_example_unicode.toml")); + + const auto the = toml::find(data, "the"); + BOOST_TEST(toml::get(the.at("test_string")) == + std::string("\xC3\x9D\xC3\xB4\xC3\xBA\x27\xE2\x84\x93\xE2\x84\x93\x20\xCE\xBB\xC3\xA1\xC6\xAD\xC3\xA8\x20\xE2\x82\xA5\xC3\xA8\x20\xC3\xA1\xC6\x92\xC6\xAD\xC3\xA8\xC5\x99\x20\xC6\xAD\xCE\xBB\xC3\xAF\xC6\xA8\x20\x2D\x20\x23")); + + const auto hard = toml::get(the.at("hard")); + const std::vector expected_the_hard_test_array{"] ", " # "}; + BOOST_CHECK(toml::get>(hard.at("test_array")) == + expected_the_hard_test_array); + const std::vector expected_the_hard_test_array2{ + std::string("\x54\xC3\xA8\xC6\xA8\xC6\xAD\x20\x23\x31\x31\x20\x5D\xC6\xA5\xC5\x99\xC3\xB4\xC6\xB2\xC3\xA8\xCE\xB4\x20\xC6\xAD\xCE\xBB\xC3\xA1\xC6\xAD"), + std::string("\xC3\x89\xD0\xB6\xC6\xA5\xC3\xA8\xC5\x99\xC3\xAF\xE2\x82\xA5\xC3\xA8\xC3\xB1\xC6\xAD\x20\x23\x39\x20\xCF\x89\xC3\xA1\xC6\xA8\x20\xC3\xA1\x20\xC6\xA8\xC3\xBA\xC3\xA7\xC3\xA7\xC3\xA8\xC6\xA8\xC6\xA8") + }; + BOOST_CHECK(toml::get>(hard.at("test_array2")) == + expected_the_hard_test_array2); + BOOST_TEST(toml::get(hard.at("another_test_string")) == + std::string("\xC2\xA7\xC3\xA1\xE2\x82\xA5\xC3\xA8\x20\xC6\xAD\xCE\xBB\xC3\xAF\xC3\xB1\xCF\xB1\x2C\x20\xCE\xB2\xC3\xBA\xC6\xAD\x20\xCF\x89\xC3\xAF\xC6\xAD\xCE\xBB\x20\xC3\xA1\x20\xC6\xA8\xC6\xAD\xC5\x99\xC3\xAF\xC3\xB1\xCF\xB1\x20\x23")); + BOOST_TEST(toml::get(hard.at("harder_test_string")) == + std::string("\x20\xC3\x82\xC3\xB1\xCE\xB4\x20\xCF\x89\xCE\xBB\xC3\xA8\xC3\xB1\x20\x22\x27\xC6\xA8\x20\xC3\xA1\xC5\x99\xC3\xA8\x20\xC3\xAF\xC3\xB1\x20\xC6\xAD\xCE\xBB\xC3\xA8\x20\xC6\xA8\xC6\xAD\xC5\x99\xC3\xAF\xC3\xB1\xCF\xB1\x2C\x20\xC3\xA1\xE2\x84\x93\xC3\xB4\xC3\xB1\xCF\xB1\x20\xCF\x89\xC3\xAF\xC6\xAD\xCE\xBB\x20\x23\x20\x22")); +// + const auto bit = toml::get(hard.at(std::string("\xCE\xB2\xC3\xAF\xC6\xAD\x23"))); + BOOST_TEST(toml::get(bit.at(std::string("\xCF\x89\xCE\xBB\xC3\xA1\xC6\xAD\x3F"))) == + std::string("\xC3\x9D\xC3\xB4\xC3\xBA\x20\xCE\xB4\xC3\xB4\xC3\xB1\x27\xC6\xAD\x20\xC6\xAD\xCE\xBB\xC3\xAF\xC3\xB1\xC6\x99\x20\xC6\xA8\xC3\xB4\xE2\x82\xA5\xC3\xA8\x20\xC3\xBA\xC6\xA8\xC3\xA8\xC5\x99\x20\xCF\x89\xC3\xB4\xC3\xB1\x27\xC6\xAD\x20\xCE\xB4\xC3\xB4\x20\xC6\xAD\xCE\xBB\xC3\xA1\xC6\xAD\x3F")); + const std::vector expected_multi_line_array{"]"}; + BOOST_CHECK(toml::get>(bit.at("multi_line_array")) == + expected_multi_line_array); +} diff --git a/external/toml11/tests/test_result.cpp b/external/toml11/tests/test_result.cpp new file mode 100644 index 0000000..ad5084c --- /dev/null +++ b/external/toml11/tests/test_result.cpp @@ -0,0 +1,440 @@ +#include + +#include "unit_test.hpp" + +#include + +BOOST_AUTO_TEST_CASE(test_construct) +{ + { + auto s = toml::ok(42); + toml::result result(s); + BOOST_TEST(!!result); + BOOST_TEST(result.is_ok()); + BOOST_TEST(!result.is_err()); + BOOST_TEST(result.unwrap() == 42); + } + { + const auto s = toml::ok(42); + toml::result result(s); + BOOST_TEST(!!result); + BOOST_TEST(result.is_ok()); + BOOST_TEST(!result.is_err()); + BOOST_TEST(result.unwrap() == 42); + } + { + toml::result result(toml::ok(42)); + BOOST_TEST(!!result); + BOOST_TEST(result.is_ok()); + BOOST_TEST(!result.is_err()); + BOOST_TEST(result.unwrap() == 42); + } + + { + auto f = toml::err("foobar"); + toml::result result(f); + BOOST_TEST(!result); + BOOST_TEST(!result.is_ok()); + BOOST_TEST(result.is_err()); + BOOST_TEST(result.unwrap_err() == "foobar"); + } + { + const auto f = toml::err("foobar"); + toml::result result(f); + BOOST_TEST(!result); + BOOST_TEST(!result.is_ok()); + BOOST_TEST(result.is_err()); + BOOST_TEST(result.unwrap_err() == "foobar"); + } + { + toml::result result(toml::err("foobar")); + BOOST_TEST(!result); + BOOST_TEST(!result.is_ok()); + BOOST_TEST(result.is_err()); + BOOST_TEST(result.unwrap_err() == "foobar"); + } +} + +BOOST_AUTO_TEST_CASE(test_assignment) +{ + { + toml::result result(toml::err("foobar")); + result = toml::ok(42); + BOOST_TEST(!!result); + BOOST_TEST(result.is_ok()); + BOOST_TEST(!result.is_err()); + BOOST_TEST(result.unwrap() == 42); + } + { + toml::result result(toml::err("foobar")); + auto s = toml::ok(42); + result = s; + BOOST_TEST(!!result); + BOOST_TEST(result.is_ok()); + BOOST_TEST(!result.is_err()); + BOOST_TEST(result.unwrap() == 42); + } + { + toml::result result(toml::err("foobar")); + const auto s = toml::ok(42); + result = s; + BOOST_TEST(!!result); + BOOST_TEST(result.is_ok()); + BOOST_TEST(!result.is_err()); + BOOST_TEST(result.unwrap() == 42); + } + { + toml::result result(toml::err("foobar")); + result = toml::err("hoge"); + BOOST_TEST(!result); + BOOST_TEST(!result.is_ok()); + BOOST_TEST(result.is_err()); + BOOST_TEST(result.unwrap_err() == "hoge"); + } + { + toml::result result(toml::err("foobar")); + auto f = toml::err("hoge"); + result = f; + BOOST_TEST(!result); + BOOST_TEST(!result.is_ok()); + BOOST_TEST(result.is_err()); + BOOST_TEST(result.unwrap_err() == "hoge"); + } + { + toml::result result(toml::err("foobar")); + const auto f = toml::err("hoge"); + result = f; + BOOST_TEST(!result); + BOOST_TEST(!result.is_ok()); + BOOST_TEST(result.is_err()); + BOOST_TEST(result.unwrap_err() == "hoge"); + } +} + +BOOST_AUTO_TEST_CASE(test_map) +{ + { + const toml::result result(toml::ok(42)); + const auto mapped = result.map( + [](const int i) -> int { + return i * 2; + }); + + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(mapped.unwrap() == 42 * 2); + } + { + toml::result, std::string> + result(toml::ok(std::unique_ptr(new int(42)))); + const auto mapped = std::move(result).map( + [](std::unique_ptr i) -> int { + return *i; + }); + + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(mapped.unwrap() == 42); + } + { + const toml::result result(toml::err("hoge")); + const auto mapped = result.map( + [](const int i) -> int { + return i * 2; + }); + + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hoge"); + } + { + toml::result, std::string> + result(toml::err("hoge")); + const auto mapped = std::move(result).map( + [](std::unique_ptr i) -> int { + return *i; + }); + + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hoge"); + } +} + +BOOST_AUTO_TEST_CASE(test_map_err) +{ + { + const toml::result result(toml::ok(42)); + const auto mapped = result.map_err( + [](const std::string s) -> std::string { + return s + s; + }); + + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(mapped.unwrap() == 42); + } + { + toml::result, std::string> + result(toml::ok(std::unique_ptr(new int(42)))); + const auto mapped = std::move(result).map_err( + [](const std::string s) -> std::string { + return s + s; + }); + + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(*(mapped.unwrap()) == 42); + } + { + const toml::result result(toml::err("hoge")); + const auto mapped = result.map_err( + [](const std::string s) -> std::string { + return s + s; + }); + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hogehoge"); + } + { + toml::result> + result(toml::err(std::unique_ptr(new std::string("hoge")))); + const auto mapped = std::move(result).map_err( + [](std::unique_ptr p) -> std::string { + return *p; + }); + + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hoge"); + } +} + +BOOST_AUTO_TEST_CASE(test_map_or_else) +{ + { + const toml::result result(toml::ok(42)); + const auto mapped = result.map_or_else( + [](const int i) -> int { + return i * 2; + }, 54); + + BOOST_TEST(mapped == 42 * 2); + } + { + toml::result, std::string> + result(toml::ok(std::unique_ptr(new int(42)))); + const auto mapped = std::move(result).map_or_else( + [](std::unique_ptr i) -> int { + return *i; + }, 54); + + BOOST_TEST(mapped == 42); + } + { + const toml::result result(toml::err("hoge")); + const auto mapped = result.map_or_else( + [](const int i) -> int { + return i * 2; + }, 54); + + BOOST_TEST(mapped == 54); + } + { + toml::result, std::string> + result(toml::err("hoge")); + const auto mapped = std::move(result).map_or_else( + [](std::unique_ptr i) -> int { + return *i; + }, 54); + + BOOST_TEST(mapped == 54); + } +} + +BOOST_AUTO_TEST_CASE(test_map_err_or_else) +{ + { + const toml::result result(toml::ok(42)); + const auto mapped = result.map_err_or_else( + [](const std::string i) -> std::string { + return i + i; + }, "foobar"); + + BOOST_TEST(mapped == "foobar"); + } + { + toml::result, std::string> + result(toml::ok(std::unique_ptr(new int(42)))); + const auto mapped = std::move(result).map_err_or_else( + [](const std::string i) -> std::string { + return i + i; + }, "foobar"); + + BOOST_TEST(mapped == "foobar"); + } + { + const toml::result result(toml::err("hoge")); + const auto mapped = result.map_err_or_else( + [](const std::string i) -> std::string { + return i + i; + }, "foobar"); + + BOOST_TEST(mapped == "hogehoge"); + } + { + toml::result, std::string> + result(toml::err("hoge")); + const auto mapped = result.map_err_or_else( + [](const std::string i) -> std::string { + return i + i; + }, "foobar"); + + BOOST_TEST(mapped == "hogehoge"); + } +} + + +BOOST_AUTO_TEST_CASE(test_and_then) +{ + { + const toml::result result(toml::ok(42)); + const auto mapped = result.and_then( + [](const int i) -> toml::result { + return toml::ok(i * 2); + }); + + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(mapped.unwrap() == 42 * 2); + } + { + toml::result, std::string> + result(toml::ok(std::unique_ptr(new int(42)))); + const auto mapped = std::move(result).and_then( + [](std::unique_ptr i) -> toml::result { + return toml::ok(*i); + }); + + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(mapped.unwrap() == 42); + } + { + const toml::result result(toml::err("hoge")); + const auto mapped = result.and_then( + [](const int i) -> toml::result { + return toml::ok(i * 2); + }); + + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hoge"); + } + { + toml::result, std::string> + result(toml::err("hoge")); + const auto mapped = std::move(result).and_then( + [](std::unique_ptr i) -> toml::result { + return toml::ok(*i); + }); + + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hoge"); + } +} + +BOOST_AUTO_TEST_CASE(test_or_else) +{ + { + const toml::result result(toml::ok(42)); + const auto mapped = result.or_else( + [](const std::string& s) -> toml::result { + return toml::err(s + s); + }); + + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(mapped.unwrap() == 42); + } + { + toml::result, std::string> + result(toml::ok(std::unique_ptr(new int(42)))); + const auto mapped = std::move(result).or_else( + [](const std::string& s) -> toml::result, std::string> { + return toml::err(s + s); + }); + + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(*mapped.unwrap() == 42); + } + { + const toml::result result(toml::err("hoge")); + const auto mapped = result.or_else( + [](const std::string& s) -> toml::result { + return toml::err(s + s); + }); + + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hogehoge"); + } + { + toml::result, std::string> + result(toml::err("hoge")); + const auto mapped = std::move(result).or_else( + [](const std::string& s) -> toml::result, std::string> { + return toml::err(s + s); + }); + + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hogehoge"); + } +} + +BOOST_AUTO_TEST_CASE(test_and_or_other) +{ + { + const toml::result r1(toml::ok(42)); + const toml::result r2(toml::err("foo")); + + BOOST_TEST(r1 == r1.or_other(r2)); + BOOST_TEST(r2 == r1.and_other(r2)); + BOOST_TEST(42 == r1.or_other(r2).unwrap()); + BOOST_TEST("foo" == r1.and_other(r2).unwrap_err()); + } + { + auto r1_gen = []() -> toml::result { + return toml::ok(42); + }; + auto r2_gen = []() -> toml::result { + return toml::err("foo"); + }; + const auto r3 = r1_gen(); + const auto r4 = r2_gen(); + + BOOST_TEST(r3 == r1_gen().or_other (r2_gen())); + BOOST_TEST(r4 == r1_gen().and_other(r2_gen())); + BOOST_TEST(42 == r1_gen().or_other (r2_gen()).unwrap()); + BOOST_TEST("foo" == r1_gen().and_other(r2_gen()).unwrap_err()); + } +} diff --git a/external/toml11/tests/test_serialize_file.cpp b/external/toml11/tests/test_serialize_file.cpp new file mode 100644 index 0000000..40cb484 --- /dev/null +++ b/external/toml11/tests/test_serialize_file.cpp @@ -0,0 +1,405 @@ +#include + +#include "unit_test.hpp" + +#include +#include +#include +#include +#include + +#include + +template class Table, + template class Array> +bool has_comment_inside(const toml::basic_value& v) +{ + if(!v.comments().empty()) + { + return false; + } + // v itself does not have a comment. + if(v.is_array()) + { + for(const auto& x : v.as_array()) + { + if(has_comment_inside(x)) + { + return false; + } + } + } + if(v.is_table()) + { + for(const auto& x : v.as_table()) + { + if(has_comment_inside(x.second)) + { + return false; + } + } + } + return true; +} + +BOOST_AUTO_TEST_CASE(test_example) +{ + const auto data = toml::parse(testinput("example.toml")); + { + std::ofstream ofs("tmp1.toml"); + ofs << std::setw(80) << data; + } + + auto serialized = toml::parse("tmp1.toml"); + { + auto& owner = toml::find(serialized, "owner"); + auto& bio = toml::find(owner, "bio"); + const auto CR = std::find(bio.begin(), bio.end(), '\r'); + if(CR != bio.end()) + { + bio.erase(CR); + } + } + BOOST_TEST(data == serialized); +} + +BOOST_AUTO_TEST_CASE(test_example_map_dq) +{ + const auto data = toml::parse( + testinput("example.toml")); + { + std::ofstream ofs("tmp1_map_dq.toml"); + ofs << std::setw(80) << data; + } + + auto serialized = toml::parse( + "tmp1_map_dq.toml"); + { + auto& owner = toml::find(serialized, "owner"); + auto& bio = toml::find(owner, "bio"); + const auto CR = std::find(bio.begin(), bio.end(), '\r'); + if(CR != bio.end()) + { + bio.erase(CR); + } + } + BOOST_TEST(data == serialized); +} + +BOOST_AUTO_TEST_CASE(test_example_with_comment) +{ + const auto data = toml::parse(testinput("example.toml")); + { + std::ofstream ofs("tmp1_com.toml"); + ofs << std::setw(80) << data; + } + + auto serialized = toml::parse("tmp1_com.toml"); + { + auto& owner = toml::find(serialized, "owner"); + auto& bio = toml::find(owner, "bio"); + const auto CR = std::find(bio.begin(), bio.end(), '\r'); + if(CR != bio.end()) + { + bio.erase(CR); + } + } + BOOST_TEST(data == serialized); + { + std::ofstream ofs("tmp1_com1.toml"); + ofs << std::setw(80) << serialized; + } +} + +BOOST_AUTO_TEST_CASE(test_example_with_comment_nocomment) +{ + { + const auto data = toml::parse(testinput("example.toml")); + { + std::ofstream ofs("tmp1_com_nocomment.toml"); + ofs << std::setw(80) << toml::nocomment << data; + } + const auto serialized = toml::parse("tmp1_com_nocomment.toml"); + // check no comment exist + BOOST_TEST(!has_comment_inside(serialized)); + } + { + const auto data_nocomment = toml::parse(testinput("example.toml")); + auto serialized = toml::parse("tmp1_com_nocomment.toml"); + { + auto& owner = toml::find(serialized, "owner"); + auto& bio = toml::find(owner, "bio"); + const auto CR = std::find(bio.begin(), bio.end(), '\r'); + if(CR != bio.end()) + { + bio.erase(CR); + } + } + // check collectly serialized + BOOST_TEST(data_nocomment == serialized); + } +} + +BOOST_AUTO_TEST_CASE(test_example_with_comment_map_dq) +{ + const auto data = toml::parse( + testinput("example.toml")); + { + std::ofstream ofs("tmp1_com_map_dq.toml"); + ofs << std::setw(80) << data; + } + + auto serialized = toml::parse( + "tmp1_com_map_dq.toml"); + { + auto& owner = toml::find(serialized, "owner"); + auto& bio = toml::find(owner, "bio"); + const auto CR = std::find(bio.begin(), bio.end(), '\r'); + if(CR != bio.end()) + { + bio.erase(CR); + } + } + BOOST_TEST(data == serialized); + { + std::ofstream ofs("tmp1_com1_map_dq.toml"); + ofs << std::setw(80) << serialized; + } +} + +BOOST_AUTO_TEST_CASE(test_example_with_comment_map_dq_nocomment) +{ + { + const auto data = toml::parse(testinput("example.toml")); + { + std::ofstream ofs("tmp1_com_map_dq_nocomment.toml"); + ofs << std::setw(80) << toml::nocomment << data; + } + const auto serialized = toml::parse("tmp1_com_map_dq_nocomment.toml"); + BOOST_TEST(!has_comment_inside(serialized)); + } + { + const auto data_nocomment = toml::parse(testinput("example.toml")); + auto serialized = toml::parse("tmp1_com_map_dq_nocomment.toml"); + { + auto& owner = toml::find(serialized, "owner"); + auto& bio = toml::find(owner, "bio"); + const auto CR = std::find(bio.begin(), bio.end(), '\r'); + if(CR != bio.end()) + { + bio.erase(CR); + } + } + BOOST_TEST(data_nocomment == serialized); + } +} + +BOOST_AUTO_TEST_CASE(test_fruit) +{ + const auto data = toml::parse(testinput("fruit.toml")); + { + std::ofstream ofs("tmp2.toml"); + ofs << std::setw(80) << data; + } + const auto serialized = toml::parse("tmp2.toml"); + BOOST_TEST(data == serialized); +} + +BOOST_AUTO_TEST_CASE(test_fruit_map_dq) +{ + const auto data = toml::parse( + testinput("fruit.toml")); + { + std::ofstream ofs("tmp2.toml"); + ofs << std::setw(80) << data; + } + const auto serialized = toml::parse( + "tmp2.toml"); + BOOST_TEST(data == serialized); +} + +BOOST_AUTO_TEST_CASE(test_fruit_with_comments) +{ + const auto data = toml::parse(testinput("fruit.toml")); + { + std::ofstream ofs("tmp2_com.toml"); + ofs << std::setw(80) << data; + } + const auto serialized = toml::parse("tmp2_com.toml"); + BOOST_TEST(data == serialized); +} + +BOOST_AUTO_TEST_CASE(test_fruit_with_comments_map_dq) +{ + const auto data = toml::parse( + testinput("fruit.toml")); + { + std::ofstream ofs("tmp2_com.toml"); + ofs << std::setw(80) << data; + } + const auto serialized = toml::parse("tmp2_com.toml"); + BOOST_TEST(data == serialized); +} + +BOOST_AUTO_TEST_CASE(test_hard_example) +{ + const auto data = toml::parse(testinput("hard_example.toml")); + { + std::ofstream ofs("tmp3.toml"); + ofs << std::setw(80) << data; + } + const auto serialized = toml::parse("tmp3.toml"); + BOOST_TEST(data == serialized); +} + +BOOST_AUTO_TEST_CASE(test_hard_example_map_dq) +{ + const auto data = toml::parse( + testinput("hard_example.toml")); + { + std::ofstream ofs("tmp3.toml"); + ofs << std::setw(80) << data; + } + const auto serialized = toml::parse( + "tmp3.toml"); + BOOST_TEST(data == serialized); +} + +BOOST_AUTO_TEST_CASE(test_hard_example_with_comment) +{ + const auto data = toml::parse( + testinput("hard_example.toml")); + { + std::ofstream ofs("tmp3_com.toml"); + ofs << std::setw(80) << data; + } + const auto serialized = toml::parse( + "tmp3_com.toml"); + { + std::ofstream ofs("tmp3_com1.toml"); + ofs << std::setw(80) << serialized; + } + BOOST_TEST(data == serialized); +} + +BOOST_AUTO_TEST_CASE(test_format_key) +{ + { + const toml::key key("normal_bare-key"); + BOOST_TEST("normal_bare-key" == toml::format_key(key)); + } + { + const toml::key key("key.include.dots"); + BOOST_TEST("\"key.include.dots\"" == toml::format_key(key)); + } + { + const toml::key key("key-include-unicode-\xE3\x81\x82"); + BOOST_TEST("\"key-include-unicode-\xE3\x81\x82\"" == toml::format_key(key)); + } + { + const toml::key key("special-chars-\\-\"-\b-\f-\r-\n-\t"); + BOOST_TEST("\"special-chars-\\\\-\\\"-\\b-\\f-\\r-\\n-\\t\"" == toml::format_key(key)); + } +} + +// In toml11, an implicitly-defined value does not have any comments. +// So, in the following file, +// ```toml +// # comment +// [[array-of-tables]] +// foo = "bar" +// ``` +// The array named "array-of-tables" does not have the comment, but the first +// element of the array has. That means that, the above file is equivalent to +// the following. +// ```toml +// array-of-tables = [ +// # comment +// {foo = "bar"}, +// ] +// ``` +// If the array itself has a comment (value_has_comment_ == true), we should try +// to make it inline. +// ```toml +// # comment about array +// array-of-tables = [ +// # comment about table element +// {foo = "bar"} +// ] +// ``` +// If it is formatted as a multiline table, the two comments becomes +// indistinguishable. +// ```toml +// # comment about array +// # comment about table element +// [[array-of-tables]] +// foo = "bar" +// ``` +// So we need to try to make it inline, and it force-inlines regardless +// of the line width limit. +// It may fail if the element of a table has comment. In that case, +// the array-of-tables will be formatted as a multiline table. +BOOST_AUTO_TEST_CASE(test_distinguish_comment) +{ + const std::string str = R"(# comment about array itself +array_of_table = [ + # comment about the first element (table) + {key = "value"}, +])"; + std::istringstream iss(str); + const auto data = toml::parse(iss); + const auto serialized = toml::format(data, /*width = */ 0); + + std::istringstream reparse(serialized); + const auto parsed = toml::parse(reparse); + + BOOST_TEST(parsed.at("array_of_table").comments().size() == 1u); + BOOST_TEST(parsed.at("array_of_table").comments().front() == " comment about array itself"); + BOOST_TEST(parsed.at("array_of_table").at(0).comments().size() == 1u); + BOOST_TEST(parsed.at("array_of_table").at(0).comments().front() == " comment about the first element (table)"); +} + + +BOOST_AUTO_TEST_CASE(test_serialize_under_locale) +{ + // avoid null init (setlocale returns null when it failed) + std::string setloc(std::setlocale(LC_ALL, nullptr)); + + // fr_FR is a one of locales that uses `,` as a decimal separator. + if(const char* try_hyphen = std::setlocale(LC_ALL, "fr_FR.UTF-8")) + { + setloc = std::string(try_hyphen); + } + else if(const char* try_nohyphen = std::setlocale(LC_ALL, "fr_FR.utf8")) + { + setloc = std::string(try_nohyphen); + } + // In some envs, fr_FR locale has not been installed. Tests must work even in such a case. +// else +// { +// BOOST_TEST(false); +// } + BOOST_TEST_MESSAGE("current locale at the beginning of the test = " << setloc); + + const std::string str = R"( +pi = 3.14159 +large_int = 1234567890 +)"; + std::istringstream iss(str); + const auto ref = toml::parse(iss); + const auto serialized_str = toml::format(ref, /*width = */ 80); + + BOOST_TEST_MESSAGE("serialized = " << serialized_str); + + std::istringstream serialized_iss(serialized_str); + const auto serialized_ref = toml::parse(serialized_iss); + + BOOST_TEST(serialized_ref.at("pi").as_floating() == ref.at("pi").as_floating()); + BOOST_TEST(serialized_ref.at("large_int").as_integer() == ref.at("large_int").as_integer()); + + const std::string endloc(std::setlocale(LC_ALL, nullptr)); + BOOST_TEST_MESSAGE("current locale at the end of the test = " << endloc); + // check if serializer change global locale + BOOST_TEST(setloc == endloc); +} diff --git a/external/toml11/tests/test_string.cpp b/external/toml11/tests/test_string.cpp new file mode 100644 index 0000000..e3f093a --- /dev/null +++ b/external/toml11/tests/test_string.cpp @@ -0,0 +1,153 @@ +#include + +#include "unit_test.hpp" + +BOOST_AUTO_TEST_CASE(test_basic_string) +{ + { + const toml::string str("basic string"); + std::ostringstream oss; + oss << str; + BOOST_TEST(oss.str() == "\"basic string\""); + } + { + const std::string s1 ("basic string"); + const toml::string str(s1); + std::ostringstream oss; + oss << str; + BOOST_TEST(oss.str() == "\"basic string\""); + } + { + const toml::string str("basic string", toml::string_t::basic); + std::ostringstream oss; + oss << str; + BOOST_TEST(oss.str() == "\"basic string\""); + } + { + const std::string s1 ("basic string"); + const toml::string str(s1, toml::string_t::basic); + std::ostringstream oss; + oss << str; + BOOST_TEST(oss.str() == "\"basic string\""); + } +} + +BOOST_AUTO_TEST_CASE(test_basic_ml_string) +{ + { + const toml::string str("basic\nstring"); + std::ostringstream oss1; + oss1 << str; + std::ostringstream oss2; + oss2 << "\"\"\"\nbasic\nstring\\\n\"\"\""; + BOOST_TEST(oss1.str() == oss2.str()); + } + { + const std::string s1 ("basic\nstring"); + const toml::string str(s1); + std::ostringstream oss1; + oss1 << str; + std::ostringstream oss2; + oss2 << "\"\"\"\nbasic\nstring\\\n\"\"\""; + BOOST_TEST(oss1.str() == oss2.str()); + } + { + const toml::string str("basic\nstring", toml::string_t::basic); + std::ostringstream oss1; + oss1 << str; + std::ostringstream oss2; + oss2 << "\"\"\"\nbasic\nstring\\\n\"\"\""; + BOOST_TEST(oss1.str() == oss2.str()); + + } + { + const std::string s1 ("basic\nstring"); + const toml::string str(s1, toml::string_t::basic); + std::ostringstream oss1; + oss1 << str; + std::ostringstream oss2; + oss2 << "\"\"\"\nbasic\nstring\\\n\"\"\""; + BOOST_TEST(oss1.str() == oss2.str()); + } +} + + +BOOST_AUTO_TEST_CASE(test_literal_string) +{ + { + const toml::string str("literal string", toml::string_t::literal); + std::ostringstream oss; + oss << str; + BOOST_TEST(oss.str() == "'literal string'"); + } + { + const std::string s1 ("literal string"); + const toml::string str(s1, toml::string_t::literal); + std::ostringstream oss; + oss << str; + BOOST_TEST(oss.str() == "'literal string'"); + } +} + +BOOST_AUTO_TEST_CASE(test_literal_ml_string) +{ + { + const toml::string str("literal\nstring", toml::string_t::literal); + std::ostringstream oss1; + oss1 << str; + std::ostringstream oss2; + oss2 << "'''\nliteral\nstring'''"; + BOOST_TEST(oss1.str() == oss2.str()); + + } + { + const std::string s1 ("literal\nstring"); + const toml::string str(s1, toml::string_t::literal); + std::ostringstream oss1; + oss1 << str; + std::ostringstream oss2; + oss2 << "'''\nliteral\nstring'''"; + BOOST_TEST(oss1.str() == oss2.str()); + } +} + +BOOST_AUTO_TEST_CASE(test_string_add_assign) +{ + // string literal + { + toml::string str("foo"); + str += "bar"; + BOOST_TEST(str.str == "foobar"); + } + // std::string + { + toml::string str("foo"); + std::string str2("bar"); + str += str2; + BOOST_TEST(str.str == "foobar"); + } + // toml::string + { + toml::string str("foo"); + toml::string str2("bar"); + str += str2; + BOOST_TEST(str.str == "foobar"); + } +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L + // std::string_view + { + toml::string str("foo"); + str += std::string_view("bar"); + BOOST_TEST(str == "foobar"); + } +#endif + // std::string += toml::string + { + std::string str("foo"); + toml::string str2("bar"); + str += str2; + BOOST_TEST(str == "foobar"); + } + + +} diff --git a/external/toml11/tests/test_traits.cpp b/external/toml11/tests/test_traits.cpp new file mode 100644 index 0000000..4d5e3e2 --- /dev/null +++ b/external/toml11/tests/test_traits.cpp @@ -0,0 +1,79 @@ +#include + +#include "unit_test.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct dummy_type{}; + +template +struct dummy_container +{ + typedef T value_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef value_type const* const_pointer; + typedef value_type const& const_reference; + typedef pointer iterator; + typedef const_pointer const_iterator; +}; + +typedef std::array std_array_type; +typedef std::map std_map_type; +typedef std::unordered_map std_unordered_map_type; + +BOOST_AUTO_TEST_CASE(test_has_xxx) +{ + BOOST_TEST(toml::detail::has_iterator>::value); + BOOST_TEST(toml::detail::has_iterator>::value); + BOOST_TEST(toml::detail::has_iterator>::value); + BOOST_TEST(toml::detail::has_iterator>::value); + BOOST_TEST(toml::detail::has_iterator>::value); + BOOST_TEST(toml::detail::has_iterator>::value); + BOOST_TEST(toml::detail::has_iterator::value); + BOOST_TEST(toml::detail::has_iterator::value); + BOOST_TEST(toml::detail::has_iterator::value); + BOOST_TEST(toml::detail::has_iterator>::value); + + BOOST_TEST(toml::detail::has_value_type>::value); + BOOST_TEST(toml::detail::has_value_type>::value); + BOOST_TEST(toml::detail::has_value_type>::value); + BOOST_TEST(toml::detail::has_value_type>::value); + BOOST_TEST(toml::detail::has_value_type::value); + BOOST_TEST(toml::detail::has_value_type>::value); + BOOST_TEST(toml::detail::has_value_type>::value); + BOOST_TEST(toml::detail::has_value_type::value); + BOOST_TEST(toml::detail::has_value_type::value); + BOOST_TEST(toml::detail::has_value_type>::value); + + BOOST_TEST(toml::detail::has_key_type::value); + BOOST_TEST(toml::detail::has_key_type::value); + BOOST_TEST(toml::detail::has_mapped_type::value); + BOOST_TEST(toml::detail::has_mapped_type::value); +} + +BOOST_AUTO_TEST_CASE(test_is_xxx) +{ + BOOST_TEST(toml::detail::is_container>::value); + BOOST_TEST(toml::detail::is_container>::value); + BOOST_TEST(toml::detail::is_container>::value); + BOOST_TEST(toml::detail::is_container>::value); + BOOST_TEST(toml::detail::is_container::value); + BOOST_TEST(toml::detail::is_container>::value); + BOOST_TEST(toml::detail::is_container>::value); + BOOST_TEST(toml::detail::is_container>::value); + + BOOST_TEST(!toml::detail::is_container::value); + BOOST_TEST(!toml::detail::is_container::value); + + BOOST_TEST(toml::detail::is_map::value); + BOOST_TEST(toml::detail::is_map::value); +} diff --git a/external/toml11/tests/test_utility.cpp b/external/toml11/tests/test_utility.cpp new file mode 100644 index 0000000..c67e3b8 --- /dev/null +++ b/external/toml11/tests/test_utility.cpp @@ -0,0 +1,45 @@ +#include + +#include "unit_test.hpp" + +#include +#include + +BOOST_AUTO_TEST_CASE(test_try_reserve) +{ + { + // since BOOST_TEST is a macro, it cannot handle commas correctly. + // When toml::detail::has_reserve_method>::value + // is passed to a macro, C preprocessor considers + // toml::detail::has_reserve_method>::value as the second argument. We need an alias to avoid + // this problem. + using reservable_type = std::vector ; + using nonreservable_type = std::array; + BOOST_TEST( toml::detail::has_reserve_method::value); + BOOST_TEST(!toml::detail::has_reserve_method::value); + } + { + std::vector v; + toml::try_reserve(v, 100); + BOOST_TEST(v.capacity() == 100u); + } +} + +BOOST_AUTO_TEST_CASE(test_concat_to_string) +{ + const std::string cat = toml::concat_to_string("foo", "bar", 42); + BOOST_TEST(cat == "foobar42"); +} + +BOOST_AUTO_TEST_CASE(test_from_string) +{ + { + const std::string str("123"); + BOOST_TEST(toml::from_string(str, 0) == 123); + } + { + const std::string str("01"); + BOOST_TEST(toml::from_string(str, 0) == 1); + } +} diff --git a/external/toml11/tests/test_value.cpp b/external/toml11/tests/test_value.cpp new file mode 100644 index 0000000..296d343 --- /dev/null +++ b/external/toml11/tests/test_value.cpp @@ -0,0 +1,1015 @@ +#include + +#include "unit_test.hpp" + +#include +#include + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L +#include +#endif + + +BOOST_AUTO_TEST_CASE(test_value_boolean) +{ + toml::value v1(true); + toml::value v2(false); + + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v2.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v2.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v2.is_boolean()); + + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v2.cast() == false); + BOOST_TEST(v1.as_boolean() == true); + BOOST_TEST(v2.as_boolean() == false); + BOOST_TEST(v1.as_boolean(std::nothrow) == true); + BOOST_TEST(v2.as_boolean(std::nothrow) == false); + + v1 = false; + v2 = true; + + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v2.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v2.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v2.is_boolean()); + + BOOST_TEST(v1.cast() == false); + BOOST_TEST(v2.cast() == true); + BOOST_TEST(v1.as_boolean() == false); + BOOST_TEST(v2.as_boolean() == true); + + toml::value v3(v1); + toml::value v4(v2); + BOOST_TEST(v3 == v1); + BOOST_TEST(v4 == v2); + + BOOST_TEST(v3.type() == toml::value_t::boolean); + BOOST_TEST(v4.type() == toml::value_t::boolean); + BOOST_TEST(v3.is(toml::value_t::boolean)); + BOOST_TEST(v4.is(toml::value_t::boolean)); + BOOST_TEST(v3.is()); + BOOST_TEST(v4.is()); + BOOST_TEST(v3.is_boolean()); + BOOST_TEST(v4.is_boolean()); + + BOOST_TEST(v3.cast() == false); + BOOST_TEST(v4.cast() == true); + BOOST_TEST(v3.as_boolean() == false); + BOOST_TEST(v4.as_boolean() == true); + + toml::value v5(std::move(v1)); + toml::value v6(std::move(v2)); + + BOOST_TEST(v5.type() == toml::value_t::boolean); + BOOST_TEST(v6.type() == toml::value_t::boolean); + BOOST_TEST(v5.is(toml::value_t::boolean)); + BOOST_TEST(v6.is(toml::value_t::boolean)); + BOOST_TEST(v5.is()); + BOOST_TEST(v6.is()); + BOOST_TEST(v3.is_boolean()); + BOOST_TEST(v4.is_boolean()); + + BOOST_TEST(v5.cast() == false); + BOOST_TEST(v6.cast() == true); + BOOST_TEST(v5.as_boolean() == false); + BOOST_TEST(v6.as_boolean() == true); + + v1 = 42; + v2 = 3.14; + + BOOST_TEST(v1.type() == toml::value_t::integer); + BOOST_TEST(v2.type() == toml::value_t::floating); + BOOST_TEST(v1.is(toml::value_t::integer)); + BOOST_TEST(v2.is(toml::value_t::floating)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_integer()); + BOOST_TEST(v2.is_floating()); + + BOOST_TEST(v1.cast() == 42); + BOOST_TEST(v2.cast() == 3.14); + BOOST_TEST(v1.as_integer() == 42); + BOOST_TEST(v2.as_floating() == 3.14); +} + +BOOST_AUTO_TEST_CASE(test_value_integer) +{ + toml::value v1(-42); + toml::value v2(42u); + + BOOST_TEST(v1.type() == toml::value_t::integer); + BOOST_TEST(v2.type() == toml::value_t::integer); + BOOST_TEST(v1.is(toml::value_t::integer)); + BOOST_TEST(v2.is(toml::value_t::integer)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_integer()); + BOOST_TEST(v2.is_integer()); + + BOOST_TEST(v1.cast() == -42); + BOOST_TEST(v2.cast() == 42u); + BOOST_TEST(v1.as_integer() == -42); + BOOST_TEST(v2.as_integer() == 42u); + BOOST_TEST(v1.as_integer(std::nothrow) == -42); + BOOST_TEST(v2.as_integer(std::nothrow) == 42u); + + v1 = 54; + v2 = -54; + + BOOST_TEST(v1.type() == toml::value_t::integer); + BOOST_TEST(v2.type() == toml::value_t::integer); + BOOST_TEST(v1.is(toml::value_t::integer)); + BOOST_TEST(v2.is(toml::value_t::integer)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_integer()); + BOOST_TEST(v2.is_integer()); + + BOOST_TEST(v1.cast() == 54); + BOOST_TEST(v2.cast() == -54); + BOOST_TEST(v1.as_integer() == 54); + BOOST_TEST(v2.as_integer() == -54); + + toml::value v3(v1); + toml::value v4(v2); + BOOST_TEST(v3 == v1); + BOOST_TEST(v4 == v2); + + BOOST_TEST(v3.type() == toml::value_t::integer); + BOOST_TEST(v4.type() == toml::value_t::integer); + BOOST_TEST(v3.is(toml::value_t::integer)); + BOOST_TEST(v4.is(toml::value_t::integer)); + BOOST_TEST(v3.is()); + BOOST_TEST(v4.is()); + BOOST_TEST(v3.is_integer()); + BOOST_TEST(v4.is_integer()); + + BOOST_TEST(v3.cast() == 54); + BOOST_TEST(v4.cast() == -54); + BOOST_TEST(v3.as_integer() == 54); + BOOST_TEST(v4.as_integer() == -54); + + toml::value v5(std::move(v1)); + toml::value v6(std::move(v2)); + + BOOST_TEST(v5.type() == toml::value_t::integer); + BOOST_TEST(v6.type() == toml::value_t::integer); + BOOST_TEST(v5.is(toml::value_t::integer)); + BOOST_TEST(v6.is(toml::value_t::integer)); + BOOST_TEST(v5.is()); + BOOST_TEST(v6.is()); + BOOST_TEST(v5.is_integer()); + BOOST_TEST(v6.is_integer()); + + BOOST_TEST(v5.cast() == 54); + BOOST_TEST(v6.cast() == -54); + BOOST_TEST(v5.as_integer() == 54); + BOOST_TEST(v6.as_integer() == -54); + + v1 = true; + v2 = false; + + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v2.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v2.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v2.is_boolean()); + + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v2.cast() == false); + BOOST_TEST(v1.as_boolean() == true); + BOOST_TEST(v2.as_boolean() == false); +} + +BOOST_AUTO_TEST_CASE(test_value_float) +{ + toml::value v1(3.14); + toml::value v2(3.14f); + + BOOST_TEST(v1.type() == toml::value_t::floating); + BOOST_TEST(v2.type() == toml::value_t::floating); + BOOST_TEST(v1.is(toml::value_t::floating)); + BOOST_TEST(v2.is(toml::value_t::floating)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_floating()); + BOOST_TEST(v2.is_floating()); + + BOOST_TEST(v1.cast() == 3.14); + BOOST_TEST(v2.cast() == 3.14, + boost::test_tools::tolerance(1e-2)); + BOOST_TEST(v1.as_floating() == 3.14); + BOOST_TEST(v2.as_floating() == 3.14, + boost::test_tools::tolerance(1e-2)); + BOOST_TEST(v1.as_floating(std::nothrow) == 3.14); + BOOST_TEST(v2.as_floating(std::nothrow) == 3.14, + boost::test_tools::tolerance(1e-2)); + + v1 = 2.718f; + v2 = 2.718; + + BOOST_TEST(v1.type() == toml::value_t::floating); + BOOST_TEST(v2.type() == toml::value_t::floating); + BOOST_TEST(v1.is(toml::value_t::floating)); + BOOST_TEST(v2.is(toml::value_t::floating)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_floating()); + BOOST_TEST(v2.is_floating()); + + BOOST_TEST(v1.cast() == 2.718, + boost::test_tools::tolerance(1e-3)); + BOOST_TEST(v2.cast() == 2.718); + BOOST_TEST(v1.as_floating() == 2.718, + boost::test_tools::tolerance(1e-3)); + BOOST_TEST(v2.as_floating() == 2.718); + + toml::value v3(v1); + toml::value v4(v2); + BOOST_TEST(v3 == v1); + BOOST_TEST(v4 == v2); + + BOOST_TEST(v3.type() == toml::value_t::floating); + BOOST_TEST(v4.type() == toml::value_t::floating); + BOOST_TEST(v3.is(toml::value_t::floating)); + BOOST_TEST(v4.is(toml::value_t::floating)); + BOOST_TEST(v3.is()); + BOOST_TEST(v4.is()); + BOOST_TEST(v3.is_floating()); + BOOST_TEST(v4.is_floating()); + + BOOST_TEST(v3.cast() == 2.718, + boost::test_tools::tolerance(1e-3)); + BOOST_TEST(v4.cast() == 2.718); + BOOST_TEST(v3.as_floating() == 2.718, + boost::test_tools::tolerance(1e-3)); + BOOST_TEST(v4.as_floating() == 2.718); + + toml::value v5(std::move(v1)); + toml::value v6(std::move(v2)); + + BOOST_TEST(v5.type() == toml::value_t::floating); + BOOST_TEST(v6.type() == toml::value_t::floating); + BOOST_TEST(v5.is(toml::value_t::floating)); + BOOST_TEST(v6.is(toml::value_t::floating)); + BOOST_TEST(v5.is()); + BOOST_TEST(v6.is()); + BOOST_TEST(v5.is_floating()); + BOOST_TEST(v6.is_floating()); + + BOOST_TEST(v5.cast() == 2.718, + boost::test_tools::tolerance(1e-3)); + BOOST_TEST(v6.cast() == 2.718); + BOOST_TEST(v5.as_floating() == 2.718, + boost::test_tools::tolerance(1e-3)); + BOOST_TEST(v6.as_floating() == 2.718); + + v1 = true; + v2 = false; + + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v2.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v2.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v2.is_boolean()); + + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v2.cast() == false); + BOOST_TEST(v1.as_boolean() == true); + BOOST_TEST(v2.as_boolean() == false); +} + +BOOST_AUTO_TEST_CASE(test_value_string) +{ + toml::value v1(std::string("foo")); + toml::value v2(std::string("foo"), toml::string_t::literal); + toml::value v3("foo"); + + BOOST_TEST(v1.type() == toml::value_t::string); + BOOST_TEST(v2.type() == toml::value_t::string); + BOOST_TEST(v3.type() == toml::value_t::string); + BOOST_TEST(v1.is(toml::value_t::string)); + BOOST_TEST(v2.is(toml::value_t::string)); + BOOST_TEST(v3.is(toml::value_t::string)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v3.is()); + BOOST_TEST(v1.is_string()); + BOOST_TEST(v2.is_string()); + BOOST_TEST(v3.is_string()); + + BOOST_TEST(v1.cast() == "foo"); + BOOST_TEST(v2.cast() == "foo"); + BOOST_TEST(v3.cast() == "foo"); + BOOST_TEST(v1.as_string() == "foo"); + BOOST_TEST(v2.as_string() == "foo"); + BOOST_TEST(v3.as_string() == "foo"); + BOOST_TEST(v1.as_string(std::nothrow) == "foo"); + BOOST_TEST(v2.as_string(std::nothrow) == "foo"); + BOOST_TEST(v3.as_string(std::nothrow) == "foo"); + + v1 = "bar"; + v2 = "bar"; + v3 = "bar"; + + BOOST_TEST(v1.type() == toml::value_t::string); + BOOST_TEST(v2.type() == toml::value_t::string); + BOOST_TEST(v3.type() == toml::value_t::string); + BOOST_TEST(v1.is(toml::value_t::string)); + BOOST_TEST(v2.is(toml::value_t::string)); + BOOST_TEST(v3.is(toml::value_t::string)); + BOOST_TEST(v1.is_string()); + BOOST_TEST(v2.is_string()); + BOOST_TEST(v3.is_string()); + + BOOST_TEST(v1.cast() == "bar"); + BOOST_TEST(v2.cast() == "bar"); + BOOST_TEST(v3.cast() == "bar"); + BOOST_TEST(v1.as_string() == "bar"); + BOOST_TEST(v2.as_string() == "bar"); + BOOST_TEST(v3.as_string() == "bar"); + + + toml::value v4(v1); + toml::value v5(v2); + toml::value v6(v3); + BOOST_TEST(v4 == v1); + BOOST_TEST(v5 == v2); + BOOST_TEST(v6 == v3); + + BOOST_TEST(v4.type() == toml::value_t::string); + BOOST_TEST(v5.type() == toml::value_t::string); + BOOST_TEST(v6.type() == toml::value_t::string); + BOOST_TEST(v4.is(toml::value_t::string)); + BOOST_TEST(v5.is(toml::value_t::string)); + BOOST_TEST(v6.is(toml::value_t::string)); + BOOST_TEST(v4.is()); + BOOST_TEST(v5.is()); + BOOST_TEST(v6.is()); + BOOST_TEST(v4.is_string()); + BOOST_TEST(v5.is_string()); + BOOST_TEST(v6.is_string()); + + BOOST_TEST(v4.cast() == "bar"); + BOOST_TEST(v5.cast() == "bar"); + BOOST_TEST(v6.cast() == "bar"); + BOOST_TEST(v4.as_string() == "bar"); + BOOST_TEST(v5.as_string() == "bar"); + BOOST_TEST(v6.as_string() == "bar"); + + + v4.cast().str.at(2) = 'z'; + v5.cast().str.at(2) = 'z'; + v6.cast().str.at(2) = 'z'; + + BOOST_TEST(v4.type() == toml::value_t::string); + BOOST_TEST(v5.type() == toml::value_t::string); + BOOST_TEST(v6.type() == toml::value_t::string); + BOOST_TEST(v4.is(toml::value_t::string)); + BOOST_TEST(v5.is(toml::value_t::string)); + BOOST_TEST(v6.is(toml::value_t::string)); + BOOST_TEST(v4.is()); + BOOST_TEST(v5.is()); + BOOST_TEST(v6.is()); + BOOST_TEST(v4.is_string()); + BOOST_TEST(v5.is_string()); + BOOST_TEST(v6.is_string()); + + BOOST_TEST(v4.as_string() == "baz"); + BOOST_TEST(v5.as_string() == "baz"); + BOOST_TEST(v6.as_string() == "baz"); + + v1 = true; + v2 = true; + v3 = true; + + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v2.type() == toml::value_t::boolean); + BOOST_TEST(v3.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v2.is(toml::value_t::boolean)); + BOOST_TEST(v3.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v3.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v2.is_boolean()); + BOOST_TEST(v3.is_boolean()); + + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v2.cast() == true); + BOOST_TEST(v3.cast() == true); + BOOST_TEST(v1.as_boolean() == true); + BOOST_TEST(v2.as_boolean() == true); + BOOST_TEST(v3.as_boolean() == true); + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L + std::string_view sv = "foo"; + + toml::value v7(sv); + toml::value v8(sv, toml::string_t::literal); + + BOOST_TEST(v7.type() == toml::value_t::string); + BOOST_TEST(v8.type() == toml::value_t::string); + BOOST_TEST(v7.is(toml::value_t::string)); + BOOST_TEST(v8.is(toml::value_t::string)); + BOOST_TEST(v7.is()); + BOOST_TEST(v8.is()); + BOOST_TEST(v7.is_string()); + BOOST_TEST(v8.is_string()); + + BOOST_TEST(v7.cast() == "foo"); + BOOST_TEST(v8.cast() == "foo"); +#endif +} + +BOOST_AUTO_TEST_CASE(test_value_local_date) +{ + toml::value v1(toml::local_date(2018, toml::month_t::Jan, 31)); + + BOOST_TEST(v1.type() == toml::value_t::local_date); + BOOST_TEST(v1.is(toml::value_t::local_date)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_local_date()); + + BOOST_TEST(v1.cast() == + toml::local_date(2018, toml::month_t::Jan, 31)); + BOOST_TEST(v1.as_local_date() == + toml::local_date(2018, toml::month_t::Jan, 31)); + BOOST_TEST(v1.as_local_date(std::nothrow) == + toml::local_date(2018, toml::month_t::Jan, 31)); + + v1 = toml::local_date(2018, toml::month_t::Apr, 1); + + BOOST_TEST(v1.type() == toml::value_t::local_date); + BOOST_TEST(v1.is(toml::value_t::local_date)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_local_date()); + + BOOST_TEST(v1.cast() == + toml::local_date(2018, toml::month_t::Apr, 1)); + BOOST_TEST(v1.as_local_date() == + toml::local_date(2018, toml::month_t::Apr, 1)); + + toml::value v2(v1); + BOOST_TEST(v2 == v1); + + BOOST_TEST(v2.type() == toml::value_t::local_date); + BOOST_TEST(v2.is(toml::value_t::local_date)); + BOOST_TEST(v2.is()); + BOOST_TEST(v2.is_local_date()); + + BOOST_TEST(v2.cast() == + toml::local_date(2018, toml::month_t::Apr, 1)); + BOOST_TEST(v2.as_local_date() == + toml::local_date(2018, toml::month_t::Apr, 1)); + + v1 = true; + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v1.as_boolean() == true); +} + +BOOST_AUTO_TEST_CASE(test_value_local_time) +{ + toml::value v1(toml::local_time(12, 30, 45)); + toml::value v2(std::chrono::hours(12) + std::chrono::minutes(30) + + std::chrono::seconds(45)); + + BOOST_TEST(v1.type() == toml::value_t::local_time); + BOOST_TEST(v2.type() == toml::value_t::local_time); + BOOST_TEST(v1.is(toml::value_t::local_time)); + BOOST_TEST(v2.is(toml::value_t::local_time)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_local_time()); + BOOST_TEST(v2.is_local_time()); + + BOOST_TEST(v1.cast() == + toml::local_time(12, 30, 45)); + BOOST_TEST(v1.as_local_time() == + toml::local_time(12, 30, 45)); + + BOOST_TEST(v2.cast() == + toml::local_time(12, 30, 45)); + BOOST_TEST(v2.as_local_time() == + toml::local_time(12, 30, 45)); + + BOOST_TEST(v1.cast() == + v2.cast()); + BOOST_TEST(v1.as_local_time() == + v2.as_local_time()); + BOOST_TEST(v1.as_local_time(std::nothrow) == + v2.as_local_time(std::nothrow)); + + v1 = toml::local_time(1, 30, 0, /*ms*/ 100, /*us*/ 0); + + BOOST_TEST(v1.type() == toml::value_t::local_time); + BOOST_TEST(v1.is(toml::value_t::local_time)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_local_time()); + BOOST_TEST(v1.cast() == + toml::local_time(1, 30, 0, 100, 0)); + BOOST_TEST(v1.as_local_time() == + toml::local_time(1, 30, 0, 100, 0)); + + toml::value v3(v1); + BOOST_TEST(v3 == v1); + + BOOST_TEST(v3.type() == toml::value_t::local_time); + BOOST_TEST(v3.is(toml::value_t::local_time)); + BOOST_TEST(v3.is()); + BOOST_TEST(v3.is_local_time()); + + BOOST_TEST(v3.cast() == + toml::local_time(1, 30, 0, 100, 0)); + BOOST_TEST(v3.as_local_time() == + toml::local_time(1, 30, 0, 100, 0)); + + v1 = true; + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v1.as_boolean() == true); +} + +BOOST_AUTO_TEST_CASE(test_value_local_datetime) +{ + toml::value v1(toml::local_datetime( + toml::local_date(2018, toml::month_t::Jan, 31), + toml::local_time(12, 30, 45) + )); + + BOOST_TEST(v1.type() == toml::value_t::local_datetime); + BOOST_TEST(v1.is(toml::value_t::local_datetime)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_local_datetime()); + + BOOST_TEST(v1.cast() == + toml::local_datetime( + toml::local_date(2018, toml::month_t::Jan, 31), + toml::local_time(12, 30, 45))); + BOOST_TEST(v1.as_local_datetime() == + toml::local_datetime( + toml::local_date(2018, toml::month_t::Jan, 31), + toml::local_time(12, 30, 45))); + BOOST_TEST(v1.as_local_datetime(std::nothrow) == + toml::local_datetime( + toml::local_date(2018, toml::month_t::Jan, 31), + toml::local_time(12, 30, 45))); + + + v1 = toml::local_datetime( + toml::local_date(2018, toml::month_t::Apr, 1), + toml::local_time(1, 15, 30)); + + BOOST_TEST(v1.type() == toml::value_t::local_datetime); + BOOST_TEST(v1.is(toml::value_t::local_datetime)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_local_datetime()); + + BOOST_TEST(v1.cast() == + toml::local_datetime( + toml::local_date(2018, toml::month_t::Apr, 1), + toml::local_time(1, 15, 30))); + BOOST_TEST(v1.as_local_datetime() == + toml::local_datetime( + toml::local_date(2018, toml::month_t::Apr, 1), + toml::local_time(1, 15, 30))); + + toml::value v2(v1); + BOOST_TEST(v2 == v1); + + BOOST_TEST(v2.type() == toml::value_t::local_datetime); + BOOST_TEST(v2.is(toml::value_t::local_datetime)); + BOOST_TEST(v2.is()); + BOOST_TEST(v2.is_local_datetime()); + + BOOST_TEST(v2.cast() == + toml::local_datetime( + toml::local_date(2018, toml::month_t::Apr, 1), + toml::local_time(1, 15, 30))); + BOOST_TEST(v2.as_local_datetime() == + toml::local_datetime( + toml::local_date(2018, toml::month_t::Apr, 1), + toml::local_time(1, 15, 30))); + + + v1 = true; + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v1.as_boolean() == true); +} + +BOOST_AUTO_TEST_CASE(test_value_offset_datetime) +{ + toml::value v1(toml::offset_datetime( + toml::local_date(2018, toml::month_t::Jan, 31), + toml::local_time(12, 30, 45), + toml::time_offset(9, 0) + )); + + BOOST_TEST(v1.type() == toml::value_t::offset_datetime); + BOOST_TEST(v1.is(toml::value_t::offset_datetime)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_offset_datetime()); + + BOOST_TEST(v1.cast() == + toml::offset_datetime( + toml::local_date(2018, toml::month_t::Jan, 31), + toml::local_time(12, 30, 45), + toml::time_offset(9, 0) + )); + BOOST_TEST(v1.as_offset_datetime() == + toml::offset_datetime( + toml::local_date(2018, toml::month_t::Jan, 31), + toml::local_time(12, 30, 45), + toml::time_offset(9, 0) + )); + BOOST_TEST(v1.as_offset_datetime(std::nothrow) == + toml::offset_datetime( + toml::local_date(2018, toml::month_t::Jan, 31), + toml::local_time(12, 30, 45), + toml::time_offset(9, 0) + )); + + + v1 = toml::offset_datetime( + toml::local_date(2018, toml::month_t::Apr, 1), + toml::local_time(1, 15, 30), + toml::time_offset(9, 0)); + + BOOST_TEST(v1.type() == toml::value_t::offset_datetime); + BOOST_TEST(v1.is(toml::value_t::offset_datetime)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_offset_datetime()); + + BOOST_TEST(v1.cast() == + toml::offset_datetime( + toml::local_date(2018, toml::month_t::Apr, 1), + toml::local_time(1, 15, 30), + toml::time_offset(9, 0))); + BOOST_TEST(v1.as_offset_datetime() == + toml::offset_datetime( + toml::local_date(2018, toml::month_t::Apr, 1), + toml::local_time(1, 15, 30), + toml::time_offset(9, 0))); + + + toml::value v2(v1); + BOOST_TEST(v2 == v1); + + BOOST_TEST(v2.type() == toml::value_t::offset_datetime); + BOOST_TEST(v2.is(toml::value_t::offset_datetime)); + BOOST_TEST(v2.is()); + BOOST_TEST(v2.is_offset_datetime()); + + BOOST_TEST(v2.cast() == + toml::offset_datetime( + toml::local_date(2018, toml::month_t::Apr, 1), + toml::local_time(1, 15, 30), + toml::time_offset(9, 0))); + BOOST_TEST(v2.as_offset_datetime() == + toml::offset_datetime( + toml::local_date(2018, toml::month_t::Apr, 1), + toml::local_time(1, 15, 30), + toml::time_offset(9, 0))); + + v1 = true; + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v1.as_boolean() == true); +} + +BOOST_AUTO_TEST_CASE(test_value_array) +{ + std::vector v{1,2,3,4,5}; + toml::value v1(v); + toml::value v2{6,7,8,9,0}; + + BOOST_TEST(v1.type() == toml::value_t::array); + BOOST_TEST(v1.is(toml::value_t::array)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_array()); + + BOOST_TEST(v2.type() == toml::value_t::array); + BOOST_TEST(v2.is(toml::value_t::array)); + BOOST_TEST(v2.is()); + BOOST_TEST(v2.is_array()); + + BOOST_TEST(v1.cast().at(0).cast() == 1); + BOOST_TEST(v1.cast().at(1).cast() == 2); + BOOST_TEST(v1.cast().at(2).cast() == 3); + BOOST_TEST(v1.cast().at(3).cast() == 4); + BOOST_TEST(v1.cast().at(4).cast() == 5); + BOOST_TEST(v1.as_array().at(0).as_integer() == 1); + BOOST_TEST(v1.as_array().at(1).as_integer() == 2); + BOOST_TEST(v1.as_array().at(2).as_integer() == 3); + BOOST_TEST(v1.as_array().at(3).as_integer() == 4); + BOOST_TEST(v1.as_array().at(4).as_integer() == 5); + BOOST_TEST(v1.as_array(std::nothrow).at(0).as_integer() == 1); + BOOST_TEST(v1.as_array(std::nothrow).at(1).as_integer() == 2); + BOOST_TEST(v1.as_array(std::nothrow).at(2).as_integer() == 3); + BOOST_TEST(v1.as_array(std::nothrow).at(3).as_integer() == 4); + BOOST_TEST(v1.as_array(std::nothrow).at(4).as_integer() == 5); + + BOOST_TEST(v2.cast().at(0).cast() == 6); + BOOST_TEST(v2.cast().at(1).cast() == 7); + BOOST_TEST(v2.cast().at(2).cast() == 8); + BOOST_TEST(v2.cast().at(3).cast() == 9); + BOOST_TEST(v2.cast().at(4).cast() == 0); + + v1 = {6,7,8,9,0}; + v2 = v; + + BOOST_TEST(v1.type() == toml::value_t::array); + BOOST_TEST(v1.is(toml::value_t::array)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_array()); + + BOOST_TEST(v2.type() == toml::value_t::array); + BOOST_TEST(v2.is(toml::value_t::array)); + BOOST_TEST(v2.is()); + BOOST_TEST(v2.is_array()); + + BOOST_TEST(v1.cast().at(0).cast() == 6); + BOOST_TEST(v1.cast().at(1).cast() == 7); + BOOST_TEST(v1.cast().at(2).cast() == 8); + BOOST_TEST(v1.cast().at(3).cast() == 9); + BOOST_TEST(v1.cast().at(4).cast() == 0); + BOOST_TEST(v1.as_array().at(0).as_integer() == 6); + BOOST_TEST(v1.as_array().at(1).as_integer() == 7); + BOOST_TEST(v1.as_array().at(2).as_integer() == 8); + BOOST_TEST(v1.as_array().at(3).as_integer() == 9); + BOOST_TEST(v1.as_array().at(4).as_integer() == 0); + + + BOOST_TEST(v2.cast().at(0).cast() == 1); + BOOST_TEST(v2.cast().at(1).cast() == 2); + BOOST_TEST(v2.cast().at(2).cast() == 3); + BOOST_TEST(v2.cast().at(3).cast() == 4); + BOOST_TEST(v2.cast().at(4).cast() == 5); + BOOST_TEST(v2.as_array().at(0).as_integer() == 1); + BOOST_TEST(v2.as_array().at(1).as_integer() == 2); + BOOST_TEST(v2.as_array().at(2).as_integer() == 3); + BOOST_TEST(v2.as_array().at(3).as_integer() == 4); + BOOST_TEST(v2.as_array().at(4).as_integer() == 5); + + + toml::value v3(v1); + BOOST_TEST(v3 == v1); + + BOOST_TEST(v3.type() == toml::value_t::array); + BOOST_TEST(v3.is(toml::value_t::array)); + BOOST_TEST(v3.is()); + BOOST_TEST(v3.is_array()); + + BOOST_TEST(v3.cast().at(0).cast() == 6); + BOOST_TEST(v3.cast().at(1).cast() == 7); + BOOST_TEST(v3.cast().at(2).cast() == 8); + BOOST_TEST(v3.cast().at(3).cast() == 9); + BOOST_TEST(v3.cast().at(4).cast() == 0); + BOOST_TEST(v3.as_array().at(0).as_integer() == 6); + BOOST_TEST(v3.as_array().at(1).as_integer() == 7); + BOOST_TEST(v3.as_array().at(2).as_integer() == 8); + BOOST_TEST(v3.as_array().at(3).as_integer() == 9); + BOOST_TEST(v3.as_array().at(4).as_integer() == 0); + + + v1 = true; + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v1.as_boolean() == true); +} + +BOOST_AUTO_TEST_CASE(test_value_table) +{ + toml::value v1{{"foo", 42}, {"bar", 3.14}, {"baz", "qux"}}; + + BOOST_TEST(v1.type() == toml::value_t::table); + BOOST_TEST(v1.is(toml::value_t::table)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_table()); + + BOOST_TEST(v1.cast().at("foo").cast() == 42); + BOOST_TEST(v1.cast().at("bar").cast() == 3.14); + BOOST_TEST(v1.cast().at("baz").cast().str == "qux"); + BOOST_TEST(v1.as_table().at("foo").as_integer() == 42); + BOOST_TEST(v1.as_table().at("bar").as_floating() == 3.14); + BOOST_TEST(v1.as_table().at("baz").as_string().str == "qux"); + BOOST_TEST(v1.as_table(std::nothrow).at("foo").as_integer() == 42); + BOOST_TEST(v1.as_table(std::nothrow).at("bar").as_floating() == 3.14); + BOOST_TEST(v1.as_table(std::nothrow).at("baz").as_string().str == "qux"); + + v1 = {{"foo", 2.71}, {"bar", 54}, {"baz", "quux"}}; + + BOOST_TEST(v1.type() == toml::value_t::table); + BOOST_TEST(v1.is(toml::value_t::table)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_table()); + + BOOST_TEST(v1.cast().at("foo").cast() == 2.71); + BOOST_TEST(v1.cast().at("bar").cast() == 54); + BOOST_TEST(v1.cast().at("baz").cast().str == "quux"); + BOOST_TEST(v1.as_table().at("foo").as_floating() == 2.71); + BOOST_TEST(v1.as_table().at("bar").as_integer() == 54); + BOOST_TEST(v1.as_table().at("baz").as_string().str == "quux"); + + v1 = toml::table{{"foo", 2.71}, {"bar", 54}, {"baz", "quux"}}; + + BOOST_TEST(v1.type() == toml::value_t::table); + BOOST_TEST(v1.is(toml::value_t::table)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_table()); + + BOOST_TEST(v1.cast().at("foo").cast() == 2.71); + BOOST_TEST(v1.cast().at("bar").cast() == 54); + BOOST_TEST(v1.cast().at("baz").cast().str == "quux"); + BOOST_TEST(v1.as_table().at("foo").as_floating() == 2.71); + BOOST_TEST(v1.as_table().at("bar").as_integer() == 54); + BOOST_TEST(v1.as_table().at("baz").as_string().str == "quux"); + + toml::value v3(v1); + BOOST_TEST(v3 == v1); + + BOOST_TEST(v3.type() == toml::value_t::table); + BOOST_TEST(v3.is(toml::value_t::table)); + BOOST_TEST(v3.is()); + BOOST_TEST(v3.is_table()); + + BOOST_TEST(v3.cast().at("foo").cast() == 2.71); + BOOST_TEST(v3.cast().at("bar").cast() == 54); + BOOST_TEST(v3.cast().at("baz").cast().str == "quux"); + BOOST_TEST(v3.as_table().at("foo").as_floating() == 2.71); + BOOST_TEST(v3.as_table().at("bar").as_integer() == 54); + BOOST_TEST(v3.as_table().at("baz").as_string().str == "quux"); + + + v1 = true; + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v1.as_boolean() == true); +} + +BOOST_AUTO_TEST_CASE(test_value_empty) +{ + toml::value v1; + BOOST_TEST(v1.is_uninitialized()); + BOOST_TEST(v1.is(toml::value_t::empty)); + + BOOST_CHECK_THROW(v1.as_boolean(), toml::type_error); + BOOST_CHECK_THROW(v1.as_integer(), toml::type_error); + BOOST_CHECK_THROW(v1.as_floating(), toml::type_error); + BOOST_CHECK_THROW(v1.as_string(), toml::type_error); + BOOST_CHECK_THROW(v1.as_offset_datetime(), toml::type_error); + BOOST_CHECK_THROW(v1.as_local_datetime(), toml::type_error); + BOOST_CHECK_THROW(v1.as_local_date(), toml::type_error); + BOOST_CHECK_THROW(v1.as_local_time(), toml::type_error); + BOOST_CHECK_THROW(v1.as_array(), toml::type_error); + BOOST_CHECK_THROW(v1.as_table(), toml::type_error); +} + + +BOOST_AUTO_TEST_CASE(test_value_at) +{ + { + toml::value v1{{"foo", 42}, {"bar", 3.14}, {"baz", "qux"}}; + + BOOST_TEST(v1.at("foo").as_integer() == 42); + BOOST_TEST(v1.at("bar").as_floating() == 3.14); + BOOST_TEST(v1.at("baz").as_string() == "qux"); + + BOOST_CHECK_THROW(v1.at(0), toml::type_error); + BOOST_CHECK_THROW(v1.at("quux"), std::out_of_range); + } + + + { + toml::value v1{1,2,3,4,5}; + + BOOST_TEST(v1.at(0).as_integer() == 1); + BOOST_TEST(v1.at(1).as_integer() == 2); + BOOST_TEST(v1.at(2).as_integer() == 3); + BOOST_TEST(v1.at(3).as_integer() == 4); + BOOST_TEST(v1.at(4).as_integer() == 5); + + BOOST_CHECK_THROW(v1.at("foo"), toml::type_error); + BOOST_CHECK_THROW(v1.at(5), std::out_of_range); + } +} + +BOOST_AUTO_TEST_CASE(test_value_bracket) +{ + { + toml::value v1{{"foo", 42}, {"bar", 3.14}, {"baz", "qux"}}; + + BOOST_TEST(v1["foo"].as_integer() == 42); + BOOST_TEST(v1["bar"].as_floating() == 3.14); + BOOST_TEST(v1["baz"].as_string() == "qux"); + + v1["qux"] = 54; + BOOST_TEST(v1["qux"].as_integer() == 54); + } + { + toml::value v1; + v1["foo"] = 42; + + BOOST_TEST(v1.is_table()); + BOOST_TEST(v1["foo"].as_integer() == 42); + } + { + toml::value v1{1,2,3,4,5}; + + BOOST_TEST(v1[0].as_integer() == 1); + BOOST_TEST(v1[1].as_integer() == 2); + BOOST_TEST(v1[2].as_integer() == 3); + BOOST_TEST(v1[3].as_integer() == 4); + BOOST_TEST(v1[4].as_integer() == 5); + + BOOST_CHECK_THROW(v1["foo"], toml::type_error); + } +} + +BOOST_AUTO_TEST_CASE(test_value_map_methods) +{ + { + toml::value v1{{"foo", 42}, {"bar", 3.14}, {"baz", "qux"}}; + + BOOST_TEST(v1.count("foo") == 1u); + BOOST_TEST(v1.count("bar") == 1u); + BOOST_TEST(v1.count("baz") == 1u); + BOOST_TEST(v1.count("qux") == 0u); + + BOOST_TEST( v1.contains("foo")); + BOOST_TEST( v1.contains("bar")); + BOOST_TEST( v1.contains("baz")); + BOOST_TEST(!v1.contains("qux")); + + BOOST_TEST(v1.size() == 3); + + v1["qux"] = 54; + BOOST_TEST(v1.count("qux") == 1u); + BOOST_TEST(v1.contains("qux")); + BOOST_TEST(v1.size() == 4); + } + { + toml::value v1(42); + BOOST_CHECK_THROW(v1.size() , toml::type_error); + BOOST_CHECK_THROW(v1.count("k") , toml::type_error); + BOOST_CHECK_THROW(v1.contains("k"), toml::type_error); + } +} + +BOOST_AUTO_TEST_CASE(test_value_vector_methods) +{ + { + toml::value v1{1, 2, 3, 4, 5}; + + BOOST_TEST(v1.size() == 5); + + v1.push_back(6); + BOOST_TEST(v1.size() == 6); + + v1.emplace_back(6); + BOOST_TEST(v1.size() == 7); + } + { + toml::value v1(42); + BOOST_CHECK_THROW(v1.size(), toml::type_error); + BOOST_CHECK_THROW(v1.push_back(1), toml::type_error); + BOOST_CHECK_THROW(v1.emplace_back(1), toml::type_error); + } +} diff --git a/external/toml11/tests/test_windows.cpp b/external/toml11/tests/test_windows.cpp new file mode 100644 index 0000000..b178a26 --- /dev/null +++ b/external/toml11/tests/test_windows.cpp @@ -0,0 +1,12 @@ +#include +#include +#include + +int main() +{ + using namespace toml::literals::toml_literals; + const auto data = R"(windows = "defines min and max as a macro")"_toml; + + std::cout << toml::find(data, "windows") << std::endl; + return 0; +} diff --git a/external/toml11/tests/unit_test.hpp b/external/toml11/tests/unit_test.hpp new file mode 100644 index 0000000..5999f57 --- /dev/null +++ b/external/toml11/tests/unit_test.hpp @@ -0,0 +1,23 @@ +#ifndef BOOST_TEST_MODULE +# error "Please #define BOOST_TEST_MODULE before you #include " +#endif + +#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST +# include +#else +# include +#endif + +#include +#include + +static inline auto testinput(const std::string& basename) -> std::string +{ + const auto this_or_that = [](const char *const s, const char *const t) { return s ? s : t; }; + std::string directory = this_or_that(std::getenv("TOMLDIR"), "toml"); + if (!directory.empty() && directory.back() != '/') + { + directory.push_back('/'); + } + return directory.append("tests/").append(basename); +} diff --git a/external/toml11/toml.hpp b/external/toml11/toml.hpp new file mode 100644 index 0000000..e975f4e --- /dev/null +++ b/external/toml11/toml.hpp @@ -0,0 +1,38 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2017 Toru Niina + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef TOML_FOR_MODERN_CPP +#define TOML_FOR_MODERN_CPP + +#define TOML11_VERSION_MAJOR 3 +#define TOML11_VERSION_MINOR 8 +#define TOML11_VERSION_PATCH 1 + +#include "toml/parser.hpp" +#include "toml/literal.hpp" +#include "toml/serializer.hpp" +#include "toml/get.hpp" +#include "toml/macros.hpp" + +#endif// TOML_FOR_MODERN_CPP diff --git a/external/toml11/toml/color.hpp b/external/toml11/toml/color.hpp new file mode 100644 index 0000000..a3fd890 --- /dev/null +++ b/external/toml11/toml/color.hpp @@ -0,0 +1,109 @@ +#ifndef TOML11_COLOR_HPP +#define TOML11_COLOR_HPP +#include +#include + +#ifdef TOML11_COLORIZE_ERROR_MESSAGE +#define TOML11_ERROR_MESSAGE_COLORIZED true +#else +#define TOML11_ERROR_MESSAGE_COLORIZED false +#endif + +namespace toml +{ + +// put ANSI escape sequence to ostream +namespace color_ansi +{ +namespace detail +{ + +inline int colorize_index() +{ + static const int index = std::ios_base::xalloc(); + return index; +} + +// Control color mode globally +class color_mode +{ + public: + inline void enable() + { + should_color_ = true; + } + inline void disable() + { + should_color_ = false; + } + + inline bool should_color() const + { + return should_color_; + } + + static color_mode& status() + { + static color_mode status_; + return status_; + } + + private: + bool should_color_ = false; +}; + +} // detail + +inline std::ostream& colorize(std::ostream& os) +{ + // by default, it is zero. + os.iword(detail::colorize_index()) = 1; + return os; +} +inline std::ostream& nocolorize(std::ostream& os) +{ + os.iword(detail::colorize_index()) = 0; + return os; +} +inline std::ostream& reset (std::ostream& os) +{if(os.iword(detail::colorize_index()) == 1) {os << "\033[00m";} return os;} +inline std::ostream& bold (std::ostream& os) +{if(os.iword(detail::colorize_index()) == 1) {os << "\033[01m";} return os;} +inline std::ostream& grey (std::ostream& os) +{if(os.iword(detail::colorize_index()) == 1) {os << "\033[30m";} return os;} +inline std::ostream& red (std::ostream& os) +{if(os.iword(detail::colorize_index()) == 1) {os << "\033[31m";} return os;} +inline std::ostream& green (std::ostream& os) +{if(os.iword(detail::colorize_index()) == 1) {os << "\033[32m";} return os;} +inline std::ostream& yellow (std::ostream& os) +{if(os.iword(detail::colorize_index()) == 1) {os << "\033[33m";} return os;} +inline std::ostream& blue (std::ostream& os) +{if(os.iword(detail::colorize_index()) == 1) {os << "\033[34m";} return os;} +inline std::ostream& magenta(std::ostream& os) +{if(os.iword(detail::colorize_index()) == 1) {os << "\033[35m";} return os;} +inline std::ostream& cyan (std::ostream& os) +{if(os.iword(detail::colorize_index()) == 1) {os << "\033[36m";} return os;} +inline std::ostream& white (std::ostream& os) +{if(os.iword(detail::colorize_index()) == 1) {os << "\033[37m";} return os;} + +inline void enable() +{ + return detail::color_mode::status().enable(); +} +inline void disable() +{ + return detail::color_mode::status().disable(); +} + +inline bool should_color() +{ + return detail::color_mode::status().should_color(); +} + +} // color_ansi + +// ANSI escape sequence is the only and default colorization method currently +namespace color = color_ansi; + +} // toml +#endif// TOML11_COLOR_HPP diff --git a/external/toml11/toml/combinator.hpp b/external/toml11/toml/combinator.hpp new file mode 100644 index 0000000..33ecca1 --- /dev/null +++ b/external/toml11/toml/combinator.hpp @@ -0,0 +1,306 @@ +// Copyright Toru Niina 2017. +// Distributed under the MIT License. +#ifndef TOML11_COMBINATOR_HPP +#define TOML11_COMBINATOR_HPP +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "region.hpp" +#include "result.hpp" +#include "traits.hpp" +#include "utility.hpp" + +// they scans characters and returns region if it matches to the condition. +// when they fail, it does not change the location. +// in lexer.hpp, these are used. + +namespace toml +{ +namespace detail +{ + +// to output character as an error message. +inline std::string show_char(const char c) +{ + // It suppresses an error that occurs only in Debug mode of MSVC++ on Windows. + // I'm not completely sure but they check the value of char to be in the + // range [0, 256) and some of the COMPLETELY VALID utf-8 character sometimes + // has negative value (if char has sign). So here it re-interprets c as + // unsigned char through pointer. In general, converting pointer to a + // pointer that has different type cause UB, but `(signed|unsigned)?char` + // are one of the exceptions. Converting pointer only to char and std::byte + // (c++17) are valid. + if(std::isgraph(*reinterpret_cast(std::addressof(c)))) + { + return std::string(1, c); + } + else + { + std::array buf; + buf.fill('\0'); + const auto r = std::snprintf( + buf.data(), buf.size(), "0x%02x", static_cast(c) & 0xFF); + (void) r; // Unused variable warning + assert(r == static_cast(buf.size()) - 1); + return std::string(buf.data()); + } +} + +template +struct character +{ + static constexpr char target = C; + + static result + invoke(location& loc) + { + if(loc.iter() == loc.end()) {return none();} + const auto first = loc.iter(); + + const char c = *(loc.iter()); + if(c != target) + { + return none(); + } + loc.advance(); // update location + + return ok(region(loc, first, loc.iter())); + } +}; +template +constexpr char character::target; + +// closed interval [Low, Up]. both Low and Up are included. +template +struct in_range +{ + // assuming ascii part of UTF-8... + static_assert(Low <= Up, "lower bound should be less than upper bound."); + + static constexpr char upper = Up; + static constexpr char lower = Low; + + static result + invoke(location& loc) + { + if(loc.iter() == loc.end()) {return none();} + const auto first = loc.iter(); + + const char c = *(loc.iter()); + if(c < lower || upper < c) + { + return none(); + } + + loc.advance(); + return ok(region(loc, first, loc.iter())); + } +}; +template constexpr char in_range::upper; +template constexpr char in_range::lower; + +// keep iterator if `Combinator` matches. otherwise, increment `iter` by 1 char. +// for detecting invalid characters, like control sequences in toml string. +template +struct exclude +{ + static result + invoke(location& loc) + { + if(loc.iter() == loc.end()) {return none();} + auto first = loc.iter(); + + auto rslt = Combinator::invoke(loc); + if(rslt.is_ok()) + { + loc.reset(first); + return none(); + } + loc.reset(std::next(first)); // XXX maybe loc.advance() is okay but... + return ok(region(loc, first, loc.iter())); + } +}; + +// increment `iter`, if matches. otherwise, just return empty string. +template +struct maybe +{ + static result + invoke(location& loc) + { + const auto rslt = Combinator::invoke(loc); + if(rslt.is_ok()) + { + return rslt; + } + return ok(region(loc)); + } +}; + +template +struct sequence; + +template +struct sequence +{ + static result + invoke(location& loc) + { + const auto first = loc.iter(); + auto rslt = Head::invoke(loc); + if(rslt.is_err()) + { + loc.reset(first); + return none(); + } + return sequence::invoke(loc, std::move(rslt.unwrap()), first); + } + + // called from the above function only, recursively. + template + static result + invoke(location& loc, region reg, Iterator first) + { + const auto rslt = Head::invoke(loc); + if(rslt.is_err()) + { + loc.reset(first); + return none(); + } + reg += rslt.unwrap(); // concat regions + return sequence::invoke(loc, std::move(reg), first); + } +}; + +template +struct sequence +{ + // would be called from sequence::invoke only. + template + static result + invoke(location& loc, region reg, Iterator first) + { + const auto rslt = Head::invoke(loc); + if(rslt.is_err()) + { + loc.reset(first); + return none(); + } + reg += rslt.unwrap(); // concat regions + return ok(reg); + } +}; + +template +struct either; + +template +struct either +{ + static result + invoke(location& loc) + { + const auto rslt = Head::invoke(loc); + if(rslt.is_ok()) {return rslt;} + return either::invoke(loc); + } +}; +template +struct either +{ + static result + invoke(location& loc) + { + return Head::invoke(loc); + } +}; + +template +struct repeat; + +template struct exactly{}; +template struct at_least{}; +struct unlimited{}; + +template +struct repeat> +{ + static result + invoke(location& loc) + { + region retval(loc); + const auto first = loc.iter(); + for(std::size_t i=0; i +struct repeat> +{ + static result + invoke(location& loc) + { + region retval(loc); + + const auto first = loc.iter(); + for(std::size_t i=0; i +struct repeat +{ + static result + invoke(location& loc) + { + region retval(loc); + while(true) + { + auto rslt = T::invoke(loc); + if(rslt.is_err()) + { + return ok(std::move(retval)); + } + retval += rslt.unwrap(); + } + } +}; + +} // detail +} // toml +#endif// TOML11_COMBINATOR_HPP diff --git a/external/toml11/toml/comments.hpp b/external/toml11/toml/comments.hpp new file mode 100644 index 0000000..c0f66f3 --- /dev/null +++ b/external/toml11/toml/comments.hpp @@ -0,0 +1,484 @@ +// Copyright Toru Niina 2019. +// Distributed under the MIT License. +#ifndef TOML11_COMMENTS_HPP +#define TOML11_COMMENTS_HPP +#include +#include +#include +#include +#include +#include +#include + +#ifdef TOML11_PRESERVE_COMMENTS_BY_DEFAULT +# define TOML11_DEFAULT_COMMENT_STRATEGY ::toml::preserve_comments +#else +# define TOML11_DEFAULT_COMMENT_STRATEGY ::toml::discard_comments +#endif + +// This file provides mainly two classes, `preserve_comments` and `discard_comments`. +// Those two are a container that have the same interface as `std::vector` +// but bahaves in the opposite way. `preserve_comments` is just the same as +// `std::vector` and each `std::string` corresponds to a comment line. +// Conversely, `discard_comments` discards all the strings and ignores everything +// assigned in it. `discard_comments` is always empty and you will encounter an +// error whenever you access to the element. +namespace toml +{ +struct discard_comments; // forward decl + +// use it in the following way +// +// const toml::basic_value data = +// toml::parse("example.toml"); +// +// the interface is almost the same as std::vector. +struct preserve_comments +{ + // `container_type` is not provided in discard_comments. + // do not use this inner-type in a generic code. + using container_type = std::vector; + + using size_type = container_type::size_type; + using difference_type = container_type::difference_type; + using value_type = container_type::value_type; + using reference = container_type::reference; + using const_reference = container_type::const_reference; + using pointer = container_type::pointer; + using const_pointer = container_type::const_pointer; + using iterator = container_type::iterator; + using const_iterator = container_type::const_iterator; + using reverse_iterator = container_type::reverse_iterator; + using const_reverse_iterator = container_type::const_reverse_iterator; + + preserve_comments() = default; + ~preserve_comments() = default; + preserve_comments(preserve_comments const&) = default; + preserve_comments(preserve_comments &&) = default; + preserve_comments& operator=(preserve_comments const&) = default; + preserve_comments& operator=(preserve_comments &&) = default; + + explicit preserve_comments(const std::vector& c): comments(c){} + explicit preserve_comments(std::vector&& c) + : comments(std::move(c)) + {} + preserve_comments& operator=(const std::vector& c) + { + comments = c; + return *this; + } + preserve_comments& operator=(std::vector&& c) + { + comments = std::move(c); + return *this; + } + + explicit preserve_comments(const discard_comments&) {} + + explicit preserve_comments(size_type n): comments(n) {} + preserve_comments(size_type n, const std::string& x): comments(n, x) {} + preserve_comments(std::initializer_list x): comments(x) {} + template + preserve_comments(InputIterator first, InputIterator last) + : comments(first, last) + {} + + template + void assign(InputIterator first, InputIterator last) {comments.assign(first, last);} + void assign(std::initializer_list ini) {comments.assign(ini);} + void assign(size_type n, const std::string& val) {comments.assign(n, val);} + + // Related to the issue #97. + // + // It is known that `std::vector::insert` and `std::vector::erase` in + // the standard library implementation included in GCC 4.8.5 takes + // `std::vector::iterator` instead of `std::vector::const_iterator`. + // Because of the const-correctness, we cannot convert a `const_iterator` to + // an `iterator`. It causes compilation error in GCC 4.8.5. +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) && !defined(__clang__) +# if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) <= 40805 +# define TOML11_WORKAROUND_GCC_4_8_X_STANDARD_LIBRARY_IMPLEMENTATION +# endif +#endif + +#ifdef TOML11_WORKAROUND_GCC_4_8_X_STANDARD_LIBRARY_IMPLEMENTATION + iterator insert(iterator p, const std::string& x) + { + return comments.insert(p, x); + } + iterator insert(iterator p, std::string&& x) + { + return comments.insert(p, std::move(x)); + } + void insert(iterator p, size_type n, const std::string& x) + { + return comments.insert(p, n, x); + } + template + void insert(iterator p, InputIterator first, InputIterator last) + { + return comments.insert(p, first, last); + } + void insert(iterator p, std::initializer_list ini) + { + return comments.insert(p, ini); + } + + template + iterator emplace(iterator p, Ts&& ... args) + { + return comments.emplace(p, std::forward(args)...); + } + + iterator erase(iterator pos) {return comments.erase(pos);} + iterator erase(iterator first, iterator last) + { + return comments.erase(first, last); + } +#else + iterator insert(const_iterator p, const std::string& x) + { + return comments.insert(p, x); + } + iterator insert(const_iterator p, std::string&& x) + { + return comments.insert(p, std::move(x)); + } + iterator insert(const_iterator p, size_type n, const std::string& x) + { + return comments.insert(p, n, x); + } + template + iterator insert(const_iterator p, InputIterator first, InputIterator last) + { + return comments.insert(p, first, last); + } + iterator insert(const_iterator p, std::initializer_list ini) + { + return comments.insert(p, ini); + } + + template + iterator emplace(const_iterator p, Ts&& ... args) + { + return comments.emplace(p, std::forward(args)...); + } + + iterator erase(const_iterator pos) {return comments.erase(pos);} + iterator erase(const_iterator first, const_iterator last) + { + return comments.erase(first, last); + } +#endif + + void swap(preserve_comments& other) {comments.swap(other.comments);} + + void push_back(const std::string& v) {comments.push_back(v);} + void push_back(std::string&& v) {comments.push_back(std::move(v));} + void pop_back() {comments.pop_back();} + + template + void emplace_back(Ts&& ... args) {comments.emplace_back(std::forward(args)...);} + + void clear() {comments.clear();} + + size_type size() const noexcept {return comments.size();} + size_type max_size() const noexcept {return comments.max_size();} + size_type capacity() const noexcept {return comments.capacity();} + bool empty() const noexcept {return comments.empty();} + + void reserve(size_type n) {comments.reserve(n);} + void resize(size_type n) {comments.resize(n);} + void resize(size_type n, const std::string& c) {comments.resize(n, c);} + void shrink_to_fit() {comments.shrink_to_fit();} + + reference operator[](const size_type n) noexcept {return comments[n];} + const_reference operator[](const size_type n) const noexcept {return comments[n];} + reference at(const size_type n) {return comments.at(n);} + const_reference at(const size_type n) const {return comments.at(n);} + reference front() noexcept {return comments.front();} + const_reference front() const noexcept {return comments.front();} + reference back() noexcept {return comments.back();} + const_reference back() const noexcept {return comments.back();} + + pointer data() noexcept {return comments.data();} + const_pointer data() const noexcept {return comments.data();} + + iterator begin() noexcept {return comments.begin();} + iterator end() noexcept {return comments.end();} + const_iterator begin() const noexcept {return comments.begin();} + const_iterator end() const noexcept {return comments.end();} + const_iterator cbegin() const noexcept {return comments.cbegin();} + const_iterator cend() const noexcept {return comments.cend();} + + reverse_iterator rbegin() noexcept {return comments.rbegin();} + reverse_iterator rend() noexcept {return comments.rend();} + const_reverse_iterator rbegin() const noexcept {return comments.rbegin();} + const_reverse_iterator rend() const noexcept {return comments.rend();} + const_reverse_iterator crbegin() const noexcept {return comments.crbegin();} + const_reverse_iterator crend() const noexcept {return comments.crend();} + + friend bool operator==(const preserve_comments&, const preserve_comments&); + friend bool operator!=(const preserve_comments&, const preserve_comments&); + friend bool operator< (const preserve_comments&, const preserve_comments&); + friend bool operator<=(const preserve_comments&, const preserve_comments&); + friend bool operator> (const preserve_comments&, const preserve_comments&); + friend bool operator>=(const preserve_comments&, const preserve_comments&); + + friend void swap(preserve_comments&, std::vector&); + friend void swap(std::vector&, preserve_comments&); + + private: + + container_type comments; +}; + +inline bool operator==(const preserve_comments& lhs, const preserve_comments& rhs) {return lhs.comments == rhs.comments;} +inline bool operator!=(const preserve_comments& lhs, const preserve_comments& rhs) {return lhs.comments != rhs.comments;} +inline bool operator< (const preserve_comments& lhs, const preserve_comments& rhs) {return lhs.comments < rhs.comments;} +inline bool operator<=(const preserve_comments& lhs, const preserve_comments& rhs) {return lhs.comments <= rhs.comments;} +inline bool operator> (const preserve_comments& lhs, const preserve_comments& rhs) {return lhs.comments > rhs.comments;} +inline bool operator>=(const preserve_comments& lhs, const preserve_comments& rhs) {return lhs.comments >= rhs.comments;} + +inline void swap(preserve_comments& lhs, preserve_comments& rhs) +{ + lhs.swap(rhs); + return; +} +inline void swap(preserve_comments& lhs, std::vector& rhs) +{ + lhs.comments.swap(rhs); + return; +} +inline void swap(std::vector& lhs, preserve_comments& rhs) +{ + lhs.swap(rhs.comments); + return; +} + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const preserve_comments& com) +{ + for(const auto& c : com) + { + os << '#' << c << '\n'; + } + return os; +} + +namespace detail +{ + +// To provide the same interface with `preserve_comments`, `discard_comments` +// should have an iterator. But it does not contain anything, so we need to +// add an iterator that points nothing. +// +// It always points null, so DO NOT unwrap this iterator. It always crashes +// your program. +template +struct empty_iterator +{ + using value_type = T; + using reference_type = typename std::conditional::type; + using pointer_type = typename std::conditional::type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::random_access_iterator_tag; + + empty_iterator() = default; + ~empty_iterator() = default; + empty_iterator(empty_iterator const&) = default; + empty_iterator(empty_iterator &&) = default; + empty_iterator& operator=(empty_iterator const&) = default; + empty_iterator& operator=(empty_iterator &&) = default; + + // DO NOT call these operators. + reference_type operator*() const noexcept {std::terminate();} + pointer_type operator->() const noexcept {return nullptr;} + reference_type operator[](difference_type) const noexcept {return this->operator*();} + + // These operators do nothing. + empty_iterator& operator++() noexcept {return *this;} + empty_iterator operator++(int) noexcept {return *this;} + empty_iterator& operator--() noexcept {return *this;} + empty_iterator operator--(int) noexcept {return *this;} + + empty_iterator& operator+=(difference_type) noexcept {return *this;} + empty_iterator& operator-=(difference_type) noexcept {return *this;} + + empty_iterator operator+(difference_type) const noexcept {return *this;} + empty_iterator operator-(difference_type) const noexcept {return *this;} +}; + +template +bool operator==(const empty_iterator&, const empty_iterator&) noexcept {return true;} +template +bool operator!=(const empty_iterator&, const empty_iterator&) noexcept {return false;} +template +bool operator< (const empty_iterator&, const empty_iterator&) noexcept {return false;} +template +bool operator<=(const empty_iterator&, const empty_iterator&) noexcept {return true;} +template +bool operator> (const empty_iterator&, const empty_iterator&) noexcept {return false;} +template +bool operator>=(const empty_iterator&, const empty_iterator&) noexcept {return true;} + +template +typename empty_iterator::difference_type +operator-(const empty_iterator&, const empty_iterator&) noexcept {return 0;} + +template +empty_iterator +operator+(typename empty_iterator::difference_type, const empty_iterator& rhs) noexcept {return rhs;} +template +empty_iterator +operator+(const empty_iterator& lhs, typename empty_iterator::difference_type) noexcept {return lhs;} + +} // detail + +// The default comment type. It discards all the comments. It requires only one +// byte to contain, so the memory footprint is smaller than preserve_comments. +// +// It just ignores `push_back`, `insert`, `erase`, and any other modifications. +// IT always returns size() == 0, the iterator taken by `begin()` is always the +// same as that of `end()`, and accessing through `operator[]` or iterators +// always causes a segmentation fault. DO NOT access to the element of this. +// +// Why this is chose as the default type is because the last version (2.x.y) +// does not contain any comments in a value. To minimize the impact on the +// efficiency, this is chosen as a default. +// +// To reduce the memory footprint, later we can try empty base optimization (EBO). +struct discard_comments +{ + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using value_type = std::string; + using reference = std::string&; + using const_reference = std::string const&; + using pointer = std::string*; + using const_pointer = std::string const*; + using iterator = detail::empty_iterator; + using const_iterator = detail::empty_iterator; + using reverse_iterator = detail::empty_iterator; + using const_reverse_iterator = detail::empty_iterator; + + discard_comments() = default; + ~discard_comments() = default; + discard_comments(discard_comments const&) = default; + discard_comments(discard_comments &&) = default; + discard_comments& operator=(discard_comments const&) = default; + discard_comments& operator=(discard_comments &&) = default; + + explicit discard_comments(const std::vector&) noexcept {} + explicit discard_comments(std::vector&&) noexcept {} + discard_comments& operator=(const std::vector&) noexcept {return *this;} + discard_comments& operator=(std::vector&&) noexcept {return *this;} + + explicit discard_comments(const preserve_comments&) noexcept {} + + explicit discard_comments(size_type) noexcept {} + discard_comments(size_type, const std::string&) noexcept {} + discard_comments(std::initializer_list) noexcept {} + template + discard_comments(InputIterator, InputIterator) noexcept {} + + template + void assign(InputIterator, InputIterator) noexcept {} + void assign(std::initializer_list) noexcept {} + void assign(size_type, const std::string&) noexcept {} + + iterator insert(const_iterator, const std::string&) {return iterator{};} + iterator insert(const_iterator, std::string&&) {return iterator{};} + iterator insert(const_iterator, size_type, const std::string&) {return iterator{};} + template + iterator insert(const_iterator, InputIterator, InputIterator) {return iterator{};} + iterator insert(const_iterator, std::initializer_list) {return iterator{};} + + template + iterator emplace(const_iterator, Ts&& ...) {return iterator{};} + iterator erase(const_iterator) {return iterator{};} + iterator erase(const_iterator, const_iterator) {return iterator{};} + + void swap(discard_comments&) {return;} + + void push_back(const std::string&) {return;} + void push_back(std::string&& ) {return;} + void pop_back() {return;} + + template + void emplace_back(Ts&& ...) {return;} + + void clear() {return;} + + size_type size() const noexcept {return 0;} + size_type max_size() const noexcept {return 0;} + size_type capacity() const noexcept {return 0;} + bool empty() const noexcept {return true;} + + void reserve(size_type) {return;} + void resize(size_type) {return;} + void resize(size_type, const std::string&) {return;} + void shrink_to_fit() {return;} + + // DO NOT access to the element of this container. This container is always + // empty, so accessing through operator[], front/back, data causes address + // error. + + reference operator[](const size_type) noexcept {never_call("toml::discard_comment::operator[]");} + const_reference operator[](const size_type) const noexcept {never_call("toml::discard_comment::operator[]");} + reference at(const size_type) {throw std::out_of_range("toml::discard_comment is always empty.");} + const_reference at(const size_type) const {throw std::out_of_range("toml::discard_comment is always empty.");} + reference front() noexcept {never_call("toml::discard_comment::front");} + const_reference front() const noexcept {never_call("toml::discard_comment::front");} + reference back() noexcept {never_call("toml::discard_comment::back");} + const_reference back() const noexcept {never_call("toml::discard_comment::back");} + + pointer data() noexcept {return nullptr;} + const_pointer data() const noexcept {return nullptr;} + + iterator begin() noexcept {return iterator{};} + iterator end() noexcept {return iterator{};} + const_iterator begin() const noexcept {return const_iterator{};} + const_iterator end() const noexcept {return const_iterator{};} + const_iterator cbegin() const noexcept {return const_iterator{};} + const_iterator cend() const noexcept {return const_iterator{};} + + reverse_iterator rbegin() noexcept {return iterator{};} + reverse_iterator rend() noexcept {return iterator{};} + const_reverse_iterator rbegin() const noexcept {return const_iterator{};} + const_reverse_iterator rend() const noexcept {return const_iterator{};} + const_reverse_iterator crbegin() const noexcept {return const_iterator{};} + const_reverse_iterator crend() const noexcept {return const_iterator{};} + + private: + + [[noreturn]] static void never_call(const char *const this_function) + { +#ifdef __has_builtin +# if __has_builtin(__builtin_unreachable) + __builtin_unreachable(); +# endif +#endif + throw std::logic_error{this_function}; + } +}; + +inline bool operator==(const discard_comments&, const discard_comments&) noexcept {return true;} +inline bool operator!=(const discard_comments&, const discard_comments&) noexcept {return false;} +inline bool operator< (const discard_comments&, const discard_comments&) noexcept {return false;} +inline bool operator<=(const discard_comments&, const discard_comments&) noexcept {return true;} +inline bool operator> (const discard_comments&, const discard_comments&) noexcept {return false;} +inline bool operator>=(const discard_comments&, const discard_comments&) noexcept {return true;} + +inline void swap(const discard_comments&, const discard_comments&) noexcept {return;} + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const discard_comments&) +{ + return os; +} + +} // toml11 +#endif// TOML11_COMMENTS_HPP diff --git a/external/toml11/toml/datetime.hpp b/external/toml11/toml/datetime.hpp new file mode 100644 index 0000000..83d04ba --- /dev/null +++ b/external/toml11/toml/datetime.hpp @@ -0,0 +1,631 @@ +// Copyright Toru Niina 2017. +// Distributed under the MIT License. +#ifndef TOML11_DATETIME_HPP +#define TOML11_DATETIME_HPP +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace toml +{ + +// To avoid non-threadsafe std::localtime. In C11 (not C++11!), localtime_s is +// provided in the absolutely same purpose, but C++11 is actually not compatible +// with C11. We need to dispatch the function depending on the OS. +namespace detail +{ +// TODO: find more sophisticated way to handle this +#if defined(_MSC_VER) +inline std::tm localtime_s(const std::time_t* src) +{ + std::tm dst; + const auto result = ::localtime_s(&dst, src); + if (result) { throw std::runtime_error("localtime_s failed."); } + return dst; +} +inline std::tm gmtime_s(const std::time_t* src) +{ + std::tm dst; + const auto result = ::gmtime_s(&dst, src); + if (result) { throw std::runtime_error("gmtime_s failed."); } + return dst; +} +#elif (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 1) || defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || defined(_POSIX_SOURCE) +inline std::tm localtime_s(const std::time_t* src) +{ + std::tm dst; + const auto result = ::localtime_r(src, &dst); + if (!result) { throw std::runtime_error("localtime_r failed."); } + return dst; +} +inline std::tm gmtime_s(const std::time_t* src) +{ + std::tm dst; + const auto result = ::gmtime_r(src, &dst); + if (!result) { throw std::runtime_error("gmtime_r failed."); } + return dst; +} +#else // fallback. not threadsafe +inline std::tm localtime_s(const std::time_t* src) +{ + const auto result = std::localtime(src); + if (!result) { throw std::runtime_error("localtime failed."); } + return *result; +} +inline std::tm gmtime_s(const std::time_t* src) +{ + const auto result = std::gmtime(src); + if (!result) { throw std::runtime_error("gmtime failed."); } + return *result; +} +#endif +} // detail + +enum class month_t : std::uint8_t +{ + Jan = 0, + Feb = 1, + Mar = 2, + Apr = 3, + May = 4, + Jun = 5, + Jul = 6, + Aug = 7, + Sep = 8, + Oct = 9, + Nov = 10, + Dec = 11 +}; + +struct local_date +{ + std::int16_t year{}; // A.D. (like, 2018) + std::uint8_t month{}; // [0, 11] + std::uint8_t day{}; // [1, 31] + + local_date(int y, month_t m, int d) + : year (static_cast(y)), + month(static_cast(m)), + day (static_cast(d)) + {} + + explicit local_date(const std::tm& t) + : year (static_cast(t.tm_year + 1900)), + month(static_cast(t.tm_mon)), + day (static_cast(t.tm_mday)) + {} + + explicit local_date(const std::chrono::system_clock::time_point& tp) + { + const auto t = std::chrono::system_clock::to_time_t(tp); + const auto time = detail::localtime_s(&t); + *this = local_date(time); + } + + explicit local_date(const std::time_t t) + : local_date(std::chrono::system_clock::from_time_t(t)) + {} + + operator std::chrono::system_clock::time_point() const + { + // std::mktime returns date as local time zone. no conversion needed + std::tm t; + t.tm_sec = 0; + t.tm_min = 0; + t.tm_hour = 0; + t.tm_mday = static_cast(this->day); + t.tm_mon = static_cast(this->month); + t.tm_year = static_cast(this->year) - 1900; + t.tm_wday = 0; // the value will be ignored + t.tm_yday = 0; // the value will be ignored + t.tm_isdst = -1; + return std::chrono::system_clock::from_time_t(std::mktime(&t)); + } + + operator std::time_t() const + { + return std::chrono::system_clock::to_time_t( + std::chrono::system_clock::time_point(*this)); + } + + local_date() = default; + ~local_date() = default; + local_date(local_date const&) = default; + local_date(local_date&&) = default; + local_date& operator=(local_date const&) = default; + local_date& operator=(local_date&&) = default; +}; + +inline bool operator==(const local_date& lhs, const local_date& rhs) +{ + return std::make_tuple(lhs.year, lhs.month, lhs.day) == + std::make_tuple(rhs.year, rhs.month, rhs.day); +} +inline bool operator!=(const local_date& lhs, const local_date& rhs) +{ + return !(lhs == rhs); +} +inline bool operator< (const local_date& lhs, const local_date& rhs) +{ + return std::make_tuple(lhs.year, lhs.month, lhs.day) < + std::make_tuple(rhs.year, rhs.month, rhs.day); +} +inline bool operator<=(const local_date& lhs, const local_date& rhs) +{ + return (lhs < rhs) || (lhs == rhs); +} +inline bool operator> (const local_date& lhs, const local_date& rhs) +{ + return !(lhs <= rhs); +} +inline bool operator>=(const local_date& lhs, const local_date& rhs) +{ + return !(lhs < rhs); +} + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const local_date& date) +{ + os << std::setfill('0') << std::setw(4) << static_cast(date.year ) << '-'; + os << std::setfill('0') << std::setw(2) << static_cast(date.month) + 1 << '-'; + os << std::setfill('0') << std::setw(2) << static_cast(date.day ) ; + return os; +} + +struct local_time +{ + std::uint8_t hour{}; // [0, 23] + std::uint8_t minute{}; // [0, 59] + std::uint8_t second{}; // [0, 60] + std::uint16_t millisecond{}; // [0, 999] + std::uint16_t microsecond{}; // [0, 999] + std::uint16_t nanosecond{}; // [0, 999] + + local_time(int h, int m, int s, + int ms = 0, int us = 0, int ns = 0) + : hour (static_cast(h)), + minute(static_cast(m)), + second(static_cast(s)), + millisecond(static_cast(ms)), + microsecond(static_cast(us)), + nanosecond (static_cast(ns)) + {} + + explicit local_time(const std::tm& t) + : hour (static_cast(t.tm_hour)), + minute(static_cast(t.tm_min)), + second(static_cast(t.tm_sec)), + millisecond(0), microsecond(0), nanosecond(0) + {} + + template + explicit local_time(const std::chrono::duration& t) + { + const auto h = std::chrono::duration_cast(t); + this->hour = static_cast(h.count()); + const auto t2 = t - h; + const auto m = std::chrono::duration_cast(t2); + this->minute = static_cast(m.count()); + const auto t3 = t2 - m; + const auto s = std::chrono::duration_cast(t3); + this->second = static_cast(s.count()); + const auto t4 = t3 - s; + const auto ms = std::chrono::duration_cast(t4); + this->millisecond = static_cast(ms.count()); + const auto t5 = t4 - ms; + const auto us = std::chrono::duration_cast(t5); + this->microsecond = static_cast(us.count()); + const auto t6 = t5 - us; + const auto ns = std::chrono::duration_cast(t6); + this->nanosecond = static_cast(ns.count()); + } + + operator std::chrono::nanoseconds() const + { + return std::chrono::nanoseconds (this->nanosecond) + + std::chrono::microseconds(this->microsecond) + + std::chrono::milliseconds(this->millisecond) + + std::chrono::seconds(this->second) + + std::chrono::minutes(this->minute) + + std::chrono::hours(this->hour); + } + + local_time() = default; + ~local_time() = default; + local_time(local_time const&) = default; + local_time(local_time&&) = default; + local_time& operator=(local_time const&) = default; + local_time& operator=(local_time&&) = default; +}; + +inline bool operator==(const local_time& lhs, const local_time& rhs) +{ + return std::make_tuple(lhs.hour, lhs.minute, lhs.second, lhs.millisecond, lhs.microsecond, lhs.nanosecond) == + std::make_tuple(rhs.hour, rhs.minute, rhs.second, rhs.millisecond, rhs.microsecond, rhs.nanosecond); +} +inline bool operator!=(const local_time& lhs, const local_time& rhs) +{ + return !(lhs == rhs); +} +inline bool operator< (const local_time& lhs, const local_time& rhs) +{ + return std::make_tuple(lhs.hour, lhs.minute, lhs.second, lhs.millisecond, lhs.microsecond, lhs.nanosecond) < + std::make_tuple(rhs.hour, rhs.minute, rhs.second, rhs.millisecond, rhs.microsecond, rhs.nanosecond); +} +inline bool operator<=(const local_time& lhs, const local_time& rhs) +{ + return (lhs < rhs) || (lhs == rhs); +} +inline bool operator> (const local_time& lhs, const local_time& rhs) +{ + return !(lhs <= rhs); +} +inline bool operator>=(const local_time& lhs, const local_time& rhs) +{ + return !(lhs < rhs); +} + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const local_time& time) +{ + os << std::setfill('0') << std::setw(2) << static_cast(time.hour ) << ':'; + os << std::setfill('0') << std::setw(2) << static_cast(time.minute) << ':'; + os << std::setfill('0') << std::setw(2) << static_cast(time.second); + if(time.millisecond != 0 || time.microsecond != 0 || time.nanosecond != 0) + { + os << '.'; + os << std::setfill('0') << std::setw(3) << static_cast(time.millisecond); + if(time.microsecond != 0 || time.nanosecond != 0) + { + os << std::setfill('0') << std::setw(3) << static_cast(time.microsecond); + if(time.nanosecond != 0) + { + os << std::setfill('0') << std::setw(3) << static_cast(time.nanosecond); + } + } + } + return os; +} + +struct time_offset +{ + std::int8_t hour{}; // [-12, 12] + std::int8_t minute{}; // [-59, 59] + + time_offset(int h, int m) + : hour (static_cast(h)), + minute(static_cast(m)) + {} + + operator std::chrono::minutes() const + { + return std::chrono::minutes(this->minute) + + std::chrono::hours(this->hour); + } + + time_offset() = default; + ~time_offset() = default; + time_offset(time_offset const&) = default; + time_offset(time_offset&&) = default; + time_offset& operator=(time_offset const&) = default; + time_offset& operator=(time_offset&&) = default; +}; + +inline bool operator==(const time_offset& lhs, const time_offset& rhs) +{ + return std::make_tuple(lhs.hour, lhs.minute) == + std::make_tuple(rhs.hour, rhs.minute); +} +inline bool operator!=(const time_offset& lhs, const time_offset& rhs) +{ + return !(lhs == rhs); +} +inline bool operator< (const time_offset& lhs, const time_offset& rhs) +{ + return std::make_tuple(lhs.hour, lhs.minute) < + std::make_tuple(rhs.hour, rhs.minute); +} +inline bool operator<=(const time_offset& lhs, const time_offset& rhs) +{ + return (lhs < rhs) || (lhs == rhs); +} +inline bool operator> (const time_offset& lhs, const time_offset& rhs) +{ + return !(lhs <= rhs); +} +inline bool operator>=(const time_offset& lhs, const time_offset& rhs) +{ + return !(lhs < rhs); +} + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const time_offset& offset) +{ + if(offset.hour == 0 && offset.minute == 0) + { + os << 'Z'; + return os; + } + int minute = static_cast(offset.hour) * 60 + offset.minute; + if(minute < 0){os << '-'; minute = std::abs(minute);} else {os << '+';} + os << std::setfill('0') << std::setw(2) << minute / 60 << ':'; + os << std::setfill('0') << std::setw(2) << minute % 60; + return os; +} + +struct local_datetime +{ + local_date date{}; + local_time time{}; + + local_datetime(local_date d, local_time t): date(d), time(t) {} + + explicit local_datetime(const std::tm& t): date(t), time(t){} + + explicit local_datetime(const std::chrono::system_clock::time_point& tp) + { + const auto t = std::chrono::system_clock::to_time_t(tp); + std::tm ltime = detail::localtime_s(&t); + + this->date = local_date(ltime); + this->time = local_time(ltime); + + // std::tm lacks subsecond information, so diff between tp and tm + // can be used to get millisecond & microsecond information. + const auto t_diff = tp - + std::chrono::system_clock::from_time_t(std::mktime(<ime)); + this->time.millisecond = static_cast( + std::chrono::duration_cast(t_diff).count()); + this->time.microsecond = static_cast( + std::chrono::duration_cast(t_diff).count()); + this->time.nanosecond = static_cast( + std::chrono::duration_cast(t_diff).count()); + } + + explicit local_datetime(const std::time_t t) + : local_datetime(std::chrono::system_clock::from_time_t(t)) + {} + + operator std::chrono::system_clock::time_point() const + { + using internal_duration = + typename std::chrono::system_clock::time_point::duration; + + // Normally DST begins at A.M. 3 or 4. If we re-use conversion operator + // of local_date and local_time independently, the conversion fails if + // it is the day when DST begins or ends. Since local_date considers the + // time is 00:00 A.M. and local_time does not consider DST because it + // does not have any date information. We need to consider both date and + // time information at the same time to convert it correctly. + + std::tm t; + t.tm_sec = static_cast(this->time.second); + t.tm_min = static_cast(this->time.minute); + t.tm_hour = static_cast(this->time.hour); + t.tm_mday = static_cast(this->date.day); + t.tm_mon = static_cast(this->date.month); + t.tm_year = static_cast(this->date.year) - 1900; + t.tm_wday = 0; // the value will be ignored + t.tm_yday = 0; // the value will be ignored + t.tm_isdst = -1; + + // std::mktime returns date as local time zone. no conversion needed + auto dt = std::chrono::system_clock::from_time_t(std::mktime(&t)); + dt += std::chrono::duration_cast( + std::chrono::milliseconds(this->time.millisecond) + + std::chrono::microseconds(this->time.microsecond) + + std::chrono::nanoseconds (this->time.nanosecond)); + return dt; + } + + operator std::time_t() const + { + return std::chrono::system_clock::to_time_t( + std::chrono::system_clock::time_point(*this)); + } + + local_datetime() = default; + ~local_datetime() = default; + local_datetime(local_datetime const&) = default; + local_datetime(local_datetime&&) = default; + local_datetime& operator=(local_datetime const&) = default; + local_datetime& operator=(local_datetime&&) = default; +}; + +inline bool operator==(const local_datetime& lhs, const local_datetime& rhs) +{ + return std::make_tuple(lhs.date, lhs.time) == + std::make_tuple(rhs.date, rhs.time); +} +inline bool operator!=(const local_datetime& lhs, const local_datetime& rhs) +{ + return !(lhs == rhs); +} +inline bool operator< (const local_datetime& lhs, const local_datetime& rhs) +{ + return std::make_tuple(lhs.date, lhs.time) < + std::make_tuple(rhs.date, rhs.time); +} +inline bool operator<=(const local_datetime& lhs, const local_datetime& rhs) +{ + return (lhs < rhs) || (lhs == rhs); +} +inline bool operator> (const local_datetime& lhs, const local_datetime& rhs) +{ + return !(lhs <= rhs); +} +inline bool operator>=(const local_datetime& lhs, const local_datetime& rhs) +{ + return !(lhs < rhs); +} + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const local_datetime& dt) +{ + os << dt.date << 'T' << dt.time; + return os; +} + +struct offset_datetime +{ + local_date date{}; + local_time time{}; + time_offset offset{}; + + offset_datetime(local_date d, local_time t, time_offset o) + : date(d), time(t), offset(o) + {} + offset_datetime(const local_datetime& dt, time_offset o) + : date(dt.date), time(dt.time), offset(o) + {} + explicit offset_datetime(const local_datetime& ld) + : date(ld.date), time(ld.time), offset(get_local_offset(nullptr)) + // use the current local timezone offset + {} + explicit offset_datetime(const std::chrono::system_clock::time_point& tp) + : offset(0, 0) // use gmtime + { + const auto timet = std::chrono::system_clock::to_time_t(tp); + const auto tm = detail::gmtime_s(&timet); + this->date = local_date(tm); + this->time = local_time(tm); + } + explicit offset_datetime(const std::time_t& t) + : offset(0, 0) // use gmtime + { + const auto tm = detail::gmtime_s(&t); + this->date = local_date(tm); + this->time = local_time(tm); + } + explicit offset_datetime(const std::tm& t) + : offset(0, 0) // assume gmtime + { + this->date = local_date(t); + this->time = local_time(t); + } + + operator std::chrono::system_clock::time_point() const + { + // get date-time + using internal_duration = + typename std::chrono::system_clock::time_point::duration; + + // first, convert it to local date-time information in the same way as + // local_datetime does. later we will use time_t to adjust time offset. + std::tm t; + t.tm_sec = static_cast(this->time.second); + t.tm_min = static_cast(this->time.minute); + t.tm_hour = static_cast(this->time.hour); + t.tm_mday = static_cast(this->date.day); + t.tm_mon = static_cast(this->date.month); + t.tm_year = static_cast(this->date.year) - 1900; + t.tm_wday = 0; // the value will be ignored + t.tm_yday = 0; // the value will be ignored + t.tm_isdst = -1; + const std::time_t tp_loc = std::mktime(std::addressof(t)); + + auto tp = std::chrono::system_clock::from_time_t(tp_loc); + tp += std::chrono::duration_cast( + std::chrono::milliseconds(this->time.millisecond) + + std::chrono::microseconds(this->time.microsecond) + + std::chrono::nanoseconds (this->time.nanosecond)); + + // Since mktime uses local time zone, it should be corrected. + // `12:00:00+09:00` means `03:00:00Z`. So mktime returns `03:00:00Z` if + // we are in `+09:00` timezone. To represent `12:00:00Z` there, we need + // to add `+09:00` to `03:00:00Z`. + // Here, it uses the time_t converted from date-time info to handle + // daylight saving time. + const auto ofs = get_local_offset(std::addressof(tp_loc)); + tp += std::chrono::hours (ofs.hour); + tp += std::chrono::minutes(ofs.minute); + + // We got `12:00:00Z` by correcting local timezone applied by mktime. + // Then we will apply the offset. Let's say `12:00:00-08:00` is given. + // And now, we have `12:00:00Z`. `12:00:00-08:00` means `20:00:00Z`. + // So we need to subtract the offset. + tp -= std::chrono::minutes(this->offset); + return tp; + } + + operator std::time_t() const + { + return std::chrono::system_clock::to_time_t( + std::chrono::system_clock::time_point(*this)); + } + + offset_datetime() = default; + ~offset_datetime() = default; + offset_datetime(offset_datetime const&) = default; + offset_datetime(offset_datetime&&) = default; + offset_datetime& operator=(offset_datetime const&) = default; + offset_datetime& operator=(offset_datetime&&) = default; + + private: + + static time_offset get_local_offset(const std::time_t* tp) + { + // get local timezone with the same date-time information as mktime + const auto t = detail::localtime_s(tp); + + std::array buf; + const auto result = std::strftime(buf.data(), 6, "%z", &t); // +hhmm\0 + if(result != 5) + { + throw std::runtime_error("toml::offset_datetime: cannot obtain " + "timezone information of current env"); + } + const int ofs = std::atoi(buf.data()); + const int ofs_h = ofs / 100; + const int ofs_m = ofs - (ofs_h * 100); + return time_offset(ofs_h, ofs_m); + } +}; + +inline bool operator==(const offset_datetime& lhs, const offset_datetime& rhs) +{ + return std::make_tuple(lhs.date, lhs.time, lhs.offset) == + std::make_tuple(rhs.date, rhs.time, rhs.offset); +} +inline bool operator!=(const offset_datetime& lhs, const offset_datetime& rhs) +{ + return !(lhs == rhs); +} +inline bool operator< (const offset_datetime& lhs, const offset_datetime& rhs) +{ + return std::make_tuple(lhs.date, lhs.time, lhs.offset) < + std::make_tuple(rhs.date, rhs.time, rhs.offset); +} +inline bool operator<=(const offset_datetime& lhs, const offset_datetime& rhs) +{ + return (lhs < rhs) || (lhs == rhs); +} +inline bool operator> (const offset_datetime& lhs, const offset_datetime& rhs) +{ + return !(lhs <= rhs); +} +inline bool operator>=(const offset_datetime& lhs, const offset_datetime& rhs) +{ + return !(lhs < rhs); +} + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const offset_datetime& dt) +{ + os << dt.date << 'T' << dt.time << dt.offset; + return os; +} + +}//toml +#endif// TOML11_DATETIME diff --git a/external/toml11/toml/exception.hpp b/external/toml11/toml/exception.hpp new file mode 100644 index 0000000..06bfe6e --- /dev/null +++ b/external/toml11/toml/exception.hpp @@ -0,0 +1,83 @@ +// Copyright Toru Niina 2017. +// Distributed under the MIT License. +#ifndef TOML11_EXCEPTION_HPP +#define TOML11_EXCEPTION_HPP + +#include +#include +#include + +#include + +#include "source_location.hpp" + +namespace toml +{ + +struct file_io_error : public std::runtime_error +{ + public: + file_io_error(int errnum, const std::string& msg, const std::string& fname) + : std::runtime_error(msg + " \"" + fname + "\": errno = " + std::to_string(errnum)), + errno_(errnum) + {} + + int get_errno() const noexcept {return errno_;} + + private: + int errno_; +}; + +struct exception : public std::exception +{ + public: + explicit exception(const source_location& loc): loc_(loc) {} + virtual ~exception() noexcept override = default; + virtual const char* what() const noexcept override {return "";} + virtual source_location const& location() const noexcept {return loc_;} + + protected: + source_location loc_; +}; + +struct syntax_error : public toml::exception +{ + public: + explicit syntax_error(const std::string& what_arg, const source_location& loc) + : exception(loc), what_(what_arg) + {} + virtual ~syntax_error() noexcept override = default; + virtual const char* what() const noexcept override {return what_.c_str();} + + protected: + std::string what_; +}; + +struct type_error : public toml::exception +{ + public: + explicit type_error(const std::string& what_arg, const source_location& loc) + : exception(loc), what_(what_arg) + {} + virtual ~type_error() noexcept override = default; + virtual const char* what() const noexcept override {return what_.c_str();} + + protected: + std::string what_; +}; + +struct internal_error : public toml::exception +{ + public: + explicit internal_error(const std::string& what_arg, const source_location& loc) + : exception(loc), what_(what_arg) + {} + virtual ~internal_error() noexcept override = default; + virtual const char* what() const noexcept override {return what_.c_str();} + + protected: + std::string what_; +}; + +} // toml +#endif // TOML_EXCEPTION diff --git a/external/toml11/toml/from.hpp b/external/toml11/toml/from.hpp new file mode 100644 index 0000000..10815ca --- /dev/null +++ b/external/toml11/toml/from.hpp @@ -0,0 +1,19 @@ +// Copyright Toru Niina 2019. +// Distributed under the MIT License. +#ifndef TOML11_FROM_HPP +#define TOML11_FROM_HPP + +namespace toml +{ + +template +struct from; +// { +// static T from_toml(const toml::value& v) +// { +// // User-defined conversions ... +// } +// }; + +} // toml +#endif // TOML11_FROM_HPP diff --git a/external/toml11/toml/get.hpp b/external/toml11/toml/get.hpp new file mode 100644 index 0000000..ac1b354 --- /dev/null +++ b/external/toml11/toml/get.hpp @@ -0,0 +1,1154 @@ +// Copyright Toru Niina 2017. +// Distributed under the MIT License. +#ifndef TOML11_GET_HPP +#define TOML11_GET_HPP +#include + +#include "from.hpp" +#include "result.hpp" +#include "value.hpp" + +namespace toml +{ + +// ============================================================================ +// exact toml::* type + +template class M, template class V> +detail::enable_if_t>::value, T> & +get(basic_value& v) +{ + return v.template cast>::value>(); +} + +template class M, template class V> +detail::enable_if_t>::value, T> const& +get(const basic_value& v) +{ + return v.template cast>::value>(); +} + +template class M, template class V> +detail::enable_if_t>::value, T> +get(basic_value&& v) +{ + return T(std::move(v).template cast>::value>()); +} + +// ============================================================================ +// T == toml::value; identity transformation. + +template class M, template class V> +inline detail::enable_if_t>::value, T>& +get(basic_value& v) +{ + return v; +} + +template class M, template class V> +inline detail::enable_if_t>::value, T> const& +get(const basic_value& v) +{ + return v; +} + +template class M, template class V> +inline detail::enable_if_t>::value, T> +get(basic_value&& v) +{ + return basic_value(std::move(v)); +} + +// ============================================================================ +// T == toml::basic_value; basic_value -> basic_value + +template class M, template class V> +inline detail::enable_if_t, + detail::negation>> + >::value, T> +get(const basic_value& v) +{ + return T(v); +} + +// ============================================================================ +// integer convertible from toml::Integer + +template class M, template class V> +inline detail::enable_if_t, // T is integral + detail::negation>, // but not bool + detail::negation< // but not toml::integer + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value& v) +{ + return static_cast(v.as_integer()); +} + +// ============================================================================ +// floating point convertible from toml::Float + +template class M, template class V> +inline detail::enable_if_t, // T is floating_point + detail::negation< // but not toml::floating + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value& v) +{ + return static_cast(v.as_floating()); +} + +// ============================================================================ +// std::string; toml uses its own toml::string, but it should be convertible to +// std::string seamlessly + +template class M, template class V> +inline detail::enable_if_t::value, std::string>& +get(basic_value& v) +{ + return v.as_string().str; +} + +template class M, template class V> +inline detail::enable_if_t::value, std::string> const& +get(const basic_value& v) +{ + return v.as_string().str; +} + +template class M, template class V> +inline detail::enable_if_t::value, std::string> +get(basic_value&& v) +{ + return std::string(std::move(v.as_string().str)); +} + +// ============================================================================ +// std::string_view + +#if defined(TOML11_USING_STRING_VIEW) && TOML11_USING_STRING_VIEW>0 +template class M, template class V> +inline detail::enable_if_t::value, std::string_view> +get(const basic_value& v) +{ + return std::string_view(v.as_string().str); +} +#endif + +// ============================================================================ +// std::chrono::duration from toml::local_time. + +template class M, template class V> +inline detail::enable_if_t::value, T> +get(const basic_value& v) +{ + return std::chrono::duration_cast( + std::chrono::nanoseconds(v.as_local_time())); +} + +// ============================================================================ +// std::chrono::system_clock::time_point from toml::datetime variants + +template class M, template class V> +inline detail::enable_if_t< + std::is_same::value, T> +get(const basic_value& v) +{ + switch(v.type()) + { + case value_t::local_date: + { + return std::chrono::system_clock::time_point(v.as_local_date()); + } + case value_t::local_datetime: + { + return std::chrono::system_clock::time_point(v.as_local_datetime()); + } + case value_t::offset_datetime: + { + return std::chrono::system_clock::time_point(v.as_offset_datetime()); + } + default: + { + throw type_error(detail::format_underline("toml::value: " + "bad_cast to std::chrono::system_clock::time_point", { + {v.location(), concat_to_string("the actual type is ", v.type())} + }), v.location()); + } + } +} + +// ============================================================================ +// forward declaration to use this recursively. ignore this and go ahead. + +// array-like type with push_back(value) method +template class M, template class V> +detail::enable_if_t, // T is a container + detail::has_push_back_method, // T::push_back(value) works + detail::negation< // but not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value&); + +// array-like type without push_back(value) method +template class M, template class V> +detail::enable_if_t, // T is a container + detail::negation>, // w/o push_back(...) + detail::negation>, // T does not have special conversion + detail::negation< // not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value&); + +// std::pair +template class M, template class V> +detail::enable_if_t::value, T> +get(const basic_value&); + +// std::tuple +template class M, template class V> +detail::enable_if_t::value, T> +get(const basic_value&); + +// map-like classes +template class M, template class V> +detail::enable_if_t, // T is map + detail::negation< // but not toml::table + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value&); + +// T.from_toml(v) +template class M, template class V> +detail::enable_if_t>>, + detail::has_from_toml_method, // but has from_toml(toml::value) + std::is_default_constructible // and default constructible + >::value, T> +get(const basic_value&); + +// toml::from::from_toml(v) +template class M, template class V> +detail::enable_if_t::value, T> +get(const basic_value&); + +template class M, template class V> +detail::enable_if_t::value, T> +get(basic_value&); + +// T(const toml::value&) and T is not toml::basic_value, +// and it does not have `from` nor `from_toml`. +template class M, template class V> +detail::enable_if_t>, + std::is_constructible&>, + detail::negation>, + detail::negation> + >::value, T> +get(const basic_value&); + +template class M, template class V> +detail::enable_if_t>, + std::is_constructible&>, + detail::negation>, + detail::negation> + >::value, T> +get(basic_value&); + +// ============================================================================ +// array-like types; most likely STL container, like std::vector, etc. + +template class M, template class V> +detail::enable_if_t, // T is a container + detail::has_push_back_method, // container.push_back(elem) works + detail::negation< // but not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value& v) +{ + using value_type = typename T::value_type; + const auto& ary = v.as_array(); + + T container; + try_reserve(container, ary.size()); + + for(const auto& elem : ary) + { + container.push_back(get(elem)); + } + return container; +} + +// ============================================================================ +// std::forward_list does not have push_back, insert, or emplace. +// It has insert_after, emplace_after, push_front. + +template class M, template class V> +detail::enable_if_t::value, T> +get(const basic_value& v) +{ + using value_type = typename T::value_type; + T container; + for(const auto& elem : v.as_array()) + { + container.push_front(get(elem)); + } + container.reverse(); + return container; +} + +// ============================================================================ +// array-like types, without push_back(). most likely [std|boost]::array. + +template class M, template class V> +detail::enable_if_t, // T is a container + detail::negation>, // w/o push_back + detail::negation>, // T does not have special conversion + detail::negation< // T is not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value& v) +{ + using value_type = typename T::value_type; + const auto& ar = v.as_array(); + + T container; + if(ar.size() != container.size()) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "toml::get: specified container size is ", container.size(), + " but there are ", ar.size(), " elements in toml array."), { + {v.location(), "here"} + })); + } + for(std::size_t i=0; i(ar[i]); + } + return container; +} + +// ============================================================================ +// std::pair. + +template class M, template class V> +detail::enable_if_t::value, T> +get(const basic_value& v) +{ + using first_type = typename T::first_type; + using second_type = typename T::second_type; + + const auto& ar = v.as_array(); + if(ar.size() != 2) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "toml::get: specified std::pair but there are ", ar.size(), + " elements in toml array."), {{v.location(), "here"}})); + } + return std::make_pair(::toml::get(ar.at(0)), + ::toml::get(ar.at(1))); +} + +// ============================================================================ +// std::tuple. + +namespace detail +{ +template +T get_tuple_impl(const Array& a, index_sequence) +{ + return std::make_tuple( + ::toml::get::type>(a.at(I))...); +} +} // detail + +template class M, template class V> +detail::enable_if_t::value, T> +get(const basic_value& v) +{ + const auto& ar = v.as_array(); + if(ar.size() != std::tuple_size::value) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "toml::get: specified std::tuple with ", + std::tuple_size::value, " elements, but there are ", ar.size(), + " elements in toml array."), {{v.location(), "here"}})); + } + return detail::get_tuple_impl(ar, + detail::make_index_sequence::value>{}); +} + +// ============================================================================ +// map-like types; most likely STL map, like std::map or std::unordered_map. + +template class M, template class V> +detail::enable_if_t, // T is map + detail::negation< // but not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value& v) +{ + using key_type = typename T::key_type; + using mapped_type = typename T::mapped_type; + static_assert(std::is_convertible::value, + "toml::get only supports map type of which key_type is " + "convertible from std::string."); + T map; + for(const auto& kv : v.as_table()) + { + map.emplace(key_type(kv.first), get(kv.second)); + } + return map; +} + +// ============================================================================ +// user-defined, but compatible types. + +template class M, template class V> +detail::enable_if_t>>, + detail::has_from_toml_method, // but has from_toml(toml::value) memfn + std::is_default_constructible // and default constructible + >::value, T> +get(const basic_value& v) +{ + T ud; + ud.from_toml(v); + return ud; +} +template class M, template class V> +detail::enable_if_t::value, T> +get(const basic_value& v) +{ + return ::toml::from::from_toml(v); +} +template class M, template class V> +detail::enable_if_t::value, T> +get(basic_value& v) +{ + return ::toml::from::from_toml(v); +} + +template class M, template class V> +detail::enable_if_t>, // T is not a toml::value + std::is_constructible&>, // T is constructible from toml::value + detail::negation>, // and T does not have T.from_toml(v); + detail::negation> // and T does not have toml::from{}; + >::value, T> +get(const basic_value& v) +{ + return T(v); +} + +template class M, template class V> +detail::enable_if_t>, // T is not a toml::value + std::is_constructible&>, // T is constructible from toml::value + detail::negation>, // and T does not have T.from_toml(v); + detail::negation> // and T does not have toml::from{}; + >::value, T> +get(basic_value& v) +{ + return T(v); +} + +// ============================================================================ +// find + +// ---------------------------------------------------------------------------- +// these overloads do not require to set T. and returns value itself. +template class M, template class V> +basic_value const& find(const basic_value& v, const key& ky) +{ + const auto& tab = v.as_table(); + if(tab.count(ky) == 0) + { + detail::throw_key_not_found_error(v, ky); + } + return tab.at(ky); +} +template class M, template class V> +basic_value& find(basic_value& v, const key& ky) +{ + auto& tab = v.as_table(); + if(tab.count(ky) == 0) + { + detail::throw_key_not_found_error(v, ky); + } + return tab.at(ky); +} +template class M, template class V> +basic_value find(basic_value&& v, const key& ky) +{ + typename basic_value::table_type tab = std::move(v).as_table(); + if(tab.count(ky) == 0) + { + detail::throw_key_not_found_error(v, ky); + } + return basic_value(std::move(tab.at(ky))); +} + +// ---------------------------------------------------------------------------- +// find(value, idx) +template class M, template class V> +basic_value const& +find(const basic_value& v, const std::size_t idx) +{ + const auto& ary = v.as_array(); + if(ary.size() <= idx) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "index ", idx, " is out of range"), {{v.location(), "in this array"}})); + } + return ary.at(idx); +} +template class M, template class V> +basic_value& find(basic_value& v, const std::size_t idx) +{ + auto& ary = v.as_array(); + if(ary.size() <= idx) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "index ", idx, " is out of range"), {{v.location(), "in this array"}})); + } + return ary.at(idx); +} +template class M, template class V> +basic_value find(basic_value&& v, const std::size_t idx) +{ + auto& ary = v.as_array(); + if(ary.size() <= idx) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "index ", idx, " is out of range"), {{v.location(), "in this array"}})); + } + return basic_value(std::move(ary.at(idx))); +} + +// ---------------------------------------------------------------------------- +// find(value, key); + +template class M, template class V> +decltype(::toml::get(std::declval const&>())) +find(const basic_value& v, const key& ky) +{ + const auto& tab = v.as_table(); + if(tab.count(ky) == 0) + { + detail::throw_key_not_found_error(v, ky); + } + return ::toml::get(tab.at(ky)); +} + +template class M, template class V> +decltype(::toml::get(std::declval&>())) +find(basic_value& v, const key& ky) +{ + auto& tab = v.as_table(); + if(tab.count(ky) == 0) + { + detail::throw_key_not_found_error(v, ky); + } + return ::toml::get(tab.at(ky)); +} + +template class M, template class V> +decltype(::toml::get(std::declval&&>())) +find(basic_value&& v, const key& ky) +{ + typename basic_value::table_type tab = std::move(v).as_table(); + if(tab.count(ky) == 0) + { + detail::throw_key_not_found_error(v, ky); + } + return ::toml::get(std::move(tab.at(ky))); +} + +// ---------------------------------------------------------------------------- +// find(value, idx) +template class M, template class V> +decltype(::toml::get(std::declval const&>())) +find(const basic_value& v, const std::size_t idx) +{ + const auto& ary = v.as_array(); + if(ary.size() <= idx) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "index ", idx, " is out of range"), {{v.location(), "in this array"}})); + } + return ::toml::get(ary.at(idx)); +} +template class M, template class V> +decltype(::toml::get(std::declval&>())) +find(basic_value& v, const std::size_t idx) +{ + auto& ary = v.as_array(); + if(ary.size() <= idx) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "index ", idx, " is out of range"), {{v.location(), "in this array"}})); + } + return ::toml::get(ary.at(idx)); +} +template class M, template class V> +decltype(::toml::get(std::declval&&>())) +find(basic_value&& v, const std::size_t idx) +{ + typename basic_value::array_type ary = std::move(v).as_array(); + if(ary.size() <= idx) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "index ", idx, " is out of range"), {{v.location(), "in this array"}})); + } + return ::toml::get(std::move(ary.at(idx))); +} + +// -------------------------------------------------------------------------- +// toml::find(toml::value, toml::key, Ts&& ... keys) + +namespace detail +{ +// It suppresses warnings by -Wsign-conversion. Let's say we have the following +// code. +// ```cpp +// const auto x = toml::find(data, "array", 0); +// ``` +// Here, the type of literal number `0` is `int`. `int` is a signed integer. +// `toml::find` takes `std::size_t` as an index. So it causes implicit sign +// conversion and `-Wsign-conversion` warns about it. Using `0u` instead of `0` +// suppresses the warning, but it makes user code messy. +// To suppress this warning, we need to be aware of type conversion caused +// by `toml::find(v, key1, key2, ... keys)`. But the thing is that the types of +// keys can be any combination of {string-like, size_t-like}. Of course we can't +// write down all the combinations. Thus we need to use some function that +// recognize the type of argument and cast it into `std::string` or +// `std::size_t` depending on the context. +// `key_cast` does the job. It has 2 overloads. One is invoked when the +// argument type is an integer and cast the argument into `std::size_t`. The +// other is invoked when the argument type is not an integer, possibly one of +// std::string, const char[N] or const char*, and construct std::string from +// the argument. +// `toml::find(v, k1, k2, ... ks)` uses `key_cast` before passing `ks` to +// `toml::find(v, k)` to suppress -Wsign-conversion. + +template +enable_if_t>, + negation, bool>>>::value, std::size_t> +key_cast(T&& v) noexcept +{ + return std::size_t(v); +} +template +enable_if_t>, + negation, bool>>>>::value, std::string> +key_cast(T&& v) noexcept +{ + return std::string(std::forward(v)); +} +} // detail + +template class M, template class V, + typename Key1, typename Key2, typename ... Keys> +const basic_value& +find(const basic_value& v, Key1&& k1, Key2&& k2, Keys&& ... keys) +{ + return ::toml::find(::toml::find(v, detail::key_cast(k1)), + detail::key_cast(k2), std::forward(keys)...); +} +template class M, template class V, + typename Key1, typename Key2, typename ... Keys> +basic_value& +find(basic_value& v, Key1&& k1, Key2&& k2, Keys&& ... keys) +{ + return ::toml::find(::toml::find(v, detail::key_cast(k1)), + detail::key_cast(k2), std::forward(keys)...); +} +template class M, template class V, + typename Key1, typename Key2, typename ... Keys> +basic_value +find(basic_value&& v, Key1&& k1, Key2&& k2, Keys&& ... keys) +{ + return ::toml::find(::toml::find(std::move(v), std::forward(k1)), + detail::key_cast(k2), std::forward(keys)...); +} + +template class M, template class V, + typename Key1, typename Key2, typename ... Keys> +decltype(::toml::get(std::declval&>())) +find(const basic_value& v, Key1&& k1, Key2&& k2, Keys&& ... keys) +{ + return ::toml::find(::toml::find(v, detail::key_cast(k1)), + detail::key_cast(k2), std::forward(keys)...); +} +template class M, template class V, + typename Key1, typename Key2, typename ... Keys> +decltype(::toml::get(std::declval&>())) +find(basic_value& v, Key1&& k1, Key2&& k2, Keys&& ... keys) +{ + return ::toml::find(::toml::find(v, detail::key_cast(k1)), + detail::key_cast(k2), std::forward(keys)...); +} +template class M, template class V, + typename Key1, typename Key2, typename ... Keys> +decltype(::toml::get(std::declval&&>())) +find(basic_value&& v, Key1&& k1, Key2&& k2, Keys&& ... keys) +{ + return ::toml::find(::toml::find(std::move(v), detail::key_cast(k1)), + detail::key_cast(k2), std::forward(keys)...); +} + +// ============================================================================ +// get_or(value, fallback) + +template class M, template class V> +basic_value const& +get_or(const basic_value& v, const basic_value&) +{ + return v; +} +template class M, template class V> +basic_value& +get_or(basic_value& v, basic_value&) +{ + return v; +} +template class M, template class V> +basic_value +get_or(basic_value&& v, basic_value&&) +{ + return v; +} + +// ---------------------------------------------------------------------------- +// specialization for the exact toml types (return type becomes lvalue ref) + +template class M, template class V> +detail::enable_if_t< + detail::is_exact_toml_type>::value, T> const& +get_or(const basic_value& v, const T& opt) +{ + try + { + return get>(v); + } + catch(...) + { + return opt; + } +} +template class M, template class V> +detail::enable_if_t< + detail::is_exact_toml_type>::value, T>& +get_or(basic_value& v, T& opt) +{ + try + { + return get>(v); + } + catch(...) + { + return opt; + } +} +template class M, template class V> +detail::enable_if_t, + basic_value>::value, detail::remove_cvref_t> +get_or(basic_value&& v, T&& opt) +{ + try + { + return get>(std::move(v)); + } + catch(...) + { + return detail::remove_cvref_t(std::forward(opt)); + } +} + +// ---------------------------------------------------------------------------- +// specialization for std::string (return type becomes lvalue ref) + +template class M, template class V> +detail::enable_if_t, std::string>::value, + std::string> const& +get_or(const basic_value& v, const T& opt) +{ + try + { + return v.as_string().str; + } + catch(...) + { + return opt; + } +} +template class M, template class V> +detail::enable_if_t::value, std::string>& +get_or(basic_value& v, T& opt) +{ + try + { + return v.as_string().str; + } + catch(...) + { + return opt; + } +} +template class M, template class V> +detail::enable_if_t< + std::is_same, std::string>::value, std::string> +get_or(basic_value&& v, T&& opt) +{ + try + { + return std::move(v.as_string().str); + } + catch(...) + { + return std::string(std::forward(opt)); + } +} + +// ---------------------------------------------------------------------------- +// specialization for string literal + +template class M, template class V> +detail::enable_if_t::type>::value, std::string> +get_or(const basic_value& v, T&& opt) +{ + try + { + return std::move(v.as_string().str); + } + catch(...) + { + return std::string(std::forward(opt)); + } +} + +// ---------------------------------------------------------------------------- +// others (require type conversion and return type cannot be lvalue reference) + +template class M, template class V> +detail::enable_if_t, + basic_value>>, + detail::negation>>, + detail::negation::type>> + >::value, detail::remove_cvref_t> +get_or(const basic_value& v, T&& opt) +{ + try + { + return get>(v); + } + catch(...) + { + return detail::remove_cvref_t(std::forward(opt)); + } +} + +// =========================================================================== +// find_or(value, key, fallback) + +template class M, template class V> +basic_value const& +find_or(const basic_value& v, const key& ky, + const basic_value& opt) +{ + if(!v.is_table()) {return opt;} + const auto& tab = v.as_table(); + if(tab.count(ky) == 0) {return opt;} + return tab.at(ky); +} + +template class M, template class V> +basic_value& +find_or(basic_value& v, const toml::key& ky, basic_value& opt) +{ + if(!v.is_table()) {return opt;} + auto& tab = v.as_table(); + if(tab.count(ky) == 0) {return opt;} + return tab.at(ky); +} + +template class M, template class V> +basic_value +find_or(basic_value&& v, const toml::key& ky, basic_value&& opt) +{ + if(!v.is_table()) {return opt;} + auto tab = std::move(v).as_table(); + if(tab.count(ky) == 0) {return opt;} + return basic_value(std::move(tab.at(ky))); +} + +// --------------------------------------------------------------------------- +// exact types (return type can be a reference) +template class M, template class V> +detail::enable_if_t< + detail::is_exact_toml_type>::value, T> const& +find_or(const basic_value& v, const key& ky, const T& opt) +{ + if(!v.is_table()) {return opt;} + const auto& tab = v.as_table(); + if(tab.count(ky) == 0) {return opt;} + return get_or(tab.at(ky), opt); +} + +template class M, template class V> +detail::enable_if_t< + detail::is_exact_toml_type>::value, T>& +find_or(basic_value& v, const toml::key& ky, T& opt) +{ + if(!v.is_table()) {return opt;} + auto& tab = v.as_table(); + if(tab.count(ky) == 0) {return opt;} + return get_or(tab.at(ky), opt); +} + +template class M, template class V> +detail::enable_if_t< + detail::is_exact_toml_type>::value, + detail::remove_cvref_t> +find_or(basic_value&& v, const toml::key& ky, T&& opt) +{ + if(!v.is_table()) {return std::forward(opt);} + auto tab = std::move(v).as_table(); + if(tab.count(ky) == 0) {return std::forward(opt);} + return get_or(std::move(tab.at(ky)), std::forward(opt)); +} + +// --------------------------------------------------------------------------- +// std::string (return type can be a reference) + +template class M, template class V> +detail::enable_if_t::value, std::string> const& +find_or(const basic_value& v, const key& ky, const T& opt) +{ + if(!v.is_table()) {return opt;} + const auto& tab = v.as_table(); + if(tab.count(ky) == 0) {return opt;} + return get_or(tab.at(ky), opt); +} +template class M, template class V> +detail::enable_if_t::value, std::string>& +find_or(basic_value& v, const toml::key& ky, T& opt) +{ + if(!v.is_table()) {return opt;} + auto& tab = v.as_table(); + if(tab.count(ky) == 0) {return opt;} + return get_or(tab.at(ky), opt); +} +template class M, template class V> +detail::enable_if_t::value, std::string> +find_or(basic_value&& v, const toml::key& ky, T&& opt) +{ + if(!v.is_table()) {return std::forward(opt);} + auto tab = std::move(v).as_table(); + if(tab.count(ky) == 0) {return std::forward(opt);} + return get_or(std::move(tab.at(ky)), std::forward(opt)); +} + +// --------------------------------------------------------------------------- +// string literal (deduced as std::string) +template class M, template class V> +detail::enable_if_t< + detail::is_string_literal::type>::value, + std::string> +find_or(const basic_value& v, const toml::key& ky, T&& opt) +{ + if(!v.is_table()) {return std::string(opt);} + const auto& tab = v.as_table(); + if(tab.count(ky) == 0) {return std::string(opt);} + return get_or(tab.at(ky), std::forward(opt)); +} + +// --------------------------------------------------------------------------- +// others (require type conversion and return type cannot be lvalue reference) +template class M, template class V> +detail::enable_if_t, basic_value>>, + // T is not std::string + detail::negation>>, + // T is not a string literal + detail::negation::type>> + >::value, detail::remove_cvref_t> +find_or(const basic_value& v, const toml::key& ky, T&& opt) +{ + if(!v.is_table()) {return std::forward(opt);} + const auto& tab = v.as_table(); + if(tab.count(ky) == 0) {return std::forward(opt);} + return get_or(tab.at(ky), std::forward(opt)); +} + +// --------------------------------------------------------------------------- +// recursive find-or with type deduction (find_or(value, keys, opt)) + +template 1), std::nullptr_t> = nullptr> + // here we need to add SFINAE in the template parameter to avoid + // infinite recursion in type deduction on gcc +auto find_or(Value&& v, const toml::key& ky, Ks&& ... keys) + -> decltype(find_or(std::forward(v), ky, detail::last_one(std::forward(keys)...))) +{ + if(!v.is_table()) + { + return detail::last_one(std::forward(keys)...); + } + auto&& tab = std::forward(v).as_table(); + if(tab.count(ky) == 0) + { + return detail::last_one(std::forward(keys)...); + } + return find_or(std::forward(tab).at(ky), std::forward(keys)...); +} + +// --------------------------------------------------------------------------- +// recursive find_or with explicit type specialization, find_or(value, keys...) + +template 1), std::nullptr_t> = nullptr> + // here we need to add SFINAE in the template parameter to avoid + // infinite recursion in type deduction on gcc +auto find_or(Value&& v, const toml::key& ky, Ks&& ... keys) + -> decltype(find_or(std::forward(v), ky, detail::last_one(std::forward(keys)...))) +{ + if(!v.is_table()) + { + return detail::last_one(std::forward(keys)...); + } + auto&& tab = std::forward(v).as_table(); + if(tab.count(ky) == 0) + { + return detail::last_one(std::forward(keys)...); + } + return find_or(std::forward(tab).at(ky), std::forward(keys)...); +} + +// ============================================================================ +// expect + +template class M, template class V> +result expect(const basic_value& v) noexcept +{ + try + { + return ok(get(v)); + } + catch(const std::exception& e) + { + return err(e.what()); + } +} +template class M, template class V> +result +expect(const basic_value& v, const toml::key& k) noexcept +{ + try + { + return ok(find(v, k)); + } + catch(const std::exception& e) + { + return err(e.what()); + } +} + +} // toml +#endif// TOML11_GET diff --git a/external/toml11/toml/into.hpp b/external/toml11/toml/into.hpp new file mode 100644 index 0000000..7449556 --- /dev/null +++ b/external/toml11/toml/into.hpp @@ -0,0 +1,19 @@ +// Copyright Toru Niina 2019. +// Distributed under the MIT License. +#ifndef TOML11_INTO_HPP +#define TOML11_INTO_HPP + +namespace toml +{ + +template +struct into; +// { +// static toml::value into_toml(const T& user_defined_type) +// { +// // User-defined conversions ... +// } +// }; + +} // toml +#endif // TOML11_INTO_HPP diff --git a/external/toml11/toml/lexer.hpp b/external/toml11/toml/lexer.hpp new file mode 100644 index 0000000..2a1ff2d --- /dev/null +++ b/external/toml11/toml/lexer.hpp @@ -0,0 +1,294 @@ +// Copyright Toru Niina 2017. +// Distributed under the MIT License. +#ifndef TOML11_LEXER_HPP +#define TOML11_LEXER_HPP +#include +#include +#include + +#include "combinator.hpp" + +namespace toml +{ +namespace detail +{ + +// these scans contents from current location in a container of char +// and extract a region that matches their own pattern. +// to see the implementation of each component, see combinator.hpp. + +using lex_wschar = either, character<'\t'>>; +using lex_ws = repeat>; +using lex_newline = either, + sequence, character<'\n'>>>; +using lex_lower = in_range<'a', 'z'>; +using lex_upper = in_range<'A', 'Z'>; +using lex_alpha = either; +using lex_digit = in_range<'0', '9'>; +using lex_nonzero = in_range<'1', '9'>; +using lex_oct_dig = in_range<'0', '7'>; +using lex_bin_dig = in_range<'0', '1'>; +using lex_hex_dig = either, in_range<'a', 'f'>>; + +using lex_hex_prefix = sequence, character<'x'>>; +using lex_oct_prefix = sequence, character<'o'>>; +using lex_bin_prefix = sequence, character<'b'>>; +using lex_underscore = character<'_'>; +using lex_plus = character<'+'>; +using lex_minus = character<'-'>; +using lex_sign = either; + +// digit | nonzero 1*(digit | _ digit) +using lex_unsigned_dec_int = either>, at_least<1>>>, + lex_digit>; +// (+|-)? unsigned_dec_int +using lex_dec_int = sequence, lex_unsigned_dec_int>; + +// hex_prefix hex_dig *(hex_dig | _ hex_dig) +using lex_hex_int = sequence>, unlimited>>>; +// oct_prefix oct_dig *(oct_dig | _ oct_dig) +using lex_oct_int = sequence>, unlimited>>>; +// bin_prefix bin_dig *(bin_dig | _ bin_dig) +using lex_bin_int = sequence>, unlimited>>>; + +// (dec_int | hex_int | oct_int | bin_int) +using lex_integer = either; + +// =========================================================================== + +using lex_inf = sequence, character<'n'>, character<'f'>>; +using lex_nan = sequence, character<'a'>, character<'n'>>; +using lex_special_float = sequence, either>; + +using lex_zero_prefixable_int = sequence>, unlimited>>; + +using lex_fractional_part = sequence, lex_zero_prefixable_int>; + +using lex_exponent_part = sequence, character<'E'>>, + maybe, lex_zero_prefixable_int>; + +using lex_float = either>>>>; + +// =========================================================================== + +using lex_true = sequence, character<'r'>, + character<'u'>, character<'e'>>; +using lex_false = sequence, character<'a'>, character<'l'>, + character<'s'>, character<'e'>>; +using lex_boolean = either; + +// =========================================================================== + +using lex_date_fullyear = repeat>; +using lex_date_month = repeat>; +using lex_date_mday = repeat>; +using lex_time_delim = either, character<'t'>, character<' '>>; +using lex_time_hour = repeat>; +using lex_time_minute = repeat>; +using lex_time_second = repeat>; +using lex_time_secfrac = sequence, + repeat>>; + +using lex_time_numoffset = sequence, character<'-'>>, + sequence, + lex_time_minute>>; +using lex_time_offset = either, character<'z'>, + lex_time_numoffset>; + +using lex_partial_time = sequence, + lex_time_minute, character<':'>, + lex_time_second, maybe>; +using lex_full_date = sequence, + lex_date_month, character<'-'>, + lex_date_mday>; +using lex_full_time = sequence; + +using lex_offset_date_time = sequence; +using lex_local_date_time = sequence; +using lex_local_date = lex_full_date; +using lex_local_time = lex_partial_time; + +// =========================================================================== + +using lex_quotation_mark = character<'"'>; +using lex_basic_unescaped = exclude, // 0x09 (tab) is allowed + in_range<0x0A, 0x1F>, + character<0x22>, character<0x5C>, + character<0x7F>>>; + +using lex_escape = character<'\\'>; +using lex_escape_unicode_short = sequence, + repeat>>; +using lex_escape_unicode_long = sequence, + repeat>>; +using lex_escape_seq_char = either, character<'\\'>, + character<'b'>, character<'f'>, + character<'n'>, character<'r'>, + character<'t'>, +#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES + character<'e'>, // ESC (0x1B) +#endif + lex_escape_unicode_short, + lex_escape_unicode_long + >; +using lex_escaped = sequence; +using lex_basic_char = either; +using lex_basic_string = sequence, + lex_quotation_mark>; + +// After toml post-v0.5.0, it is explicitly clarified how quotes in ml-strings +// are allowed to be used. +// After this, the following strings are *explicitly* allowed. +// - One or two `"`s in a multi-line basic string is allowed wherever it is. +// - Three consecutive `"`s in a multi-line basic string is considered as a delimiter. +// - One or two `"`s can appear just before or after the delimiter. +// ```toml +// str4 = """Here are two quotation marks: "". Simple enough.""" +// str5 = """Here are three quotation marks: ""\".""" +// str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\".""" +// str7 = """"This," she said, "is just a pointless statement."""" +// ``` +// In the current implementation (v3.3.0), it is difficult to parse `str7` in +// the above example. It is difficult to recognize `"` at the end of string body +// collectly. It will be misunderstood as a `"""` delimiter and an additional, +// invalid `"`. Like this: +// ```console +// what(): [error] toml::parse_table: invalid line format +// --> hoge.toml +// | +// 13 | str7 = """"This," she said, "is just a pointless statement."""" +// | ^- expected newline, but got '"'. +// ``` +// As a quick workaround for this problem, `lex_ml_basic_string_delim` was +// split into two, `lex_ml_basic_string_open` and `lex_ml_basic_string_close`. +// `lex_ml_basic_string_open` allows only `"""`. `_close` allows 3-5 `"`s. +// In parse_ml_basic_string() function, the trailing `"`s will be attached to +// the string body. +// +using lex_ml_basic_string_delim = repeat>; +using lex_ml_basic_string_open = lex_ml_basic_string_delim; +using lex_ml_basic_string_close = sequence< + repeat>, + maybe, maybe + >; + +using lex_ml_basic_unescaped = exclude, // 0x09 is tab + in_range<0x0A, 0x1F>, + character<0x5C>, // backslash + character<0x7F>, // DEL + lex_ml_basic_string_delim>>; + +using lex_ml_basic_escaped_newline = sequence< + lex_escape, maybe, lex_newline, + repeat, unlimited>>; + +using lex_ml_basic_char = either; +using lex_ml_basic_body = repeat, + unlimited>; +using lex_ml_basic_string = sequence; + +using lex_literal_char = exclude, in_range<0x0A, 0x1F>, + character<0x7F>, character<0x27>>>; +using lex_apostrophe = character<'\''>; +using lex_literal_string = sequence, + lex_apostrophe>; + +// the same reason as above. +using lex_ml_literal_string_delim = repeat>; +using lex_ml_literal_string_open = lex_ml_literal_string_delim; +using lex_ml_literal_string_close = sequence< + repeat>, + maybe, maybe + >; + +using lex_ml_literal_char = exclude, + in_range<0x0A, 0x1F>, + character<0x7F>, + lex_ml_literal_string_delim>>; +using lex_ml_literal_body = repeat, + unlimited>; +using lex_ml_literal_string = sequence; + +using lex_string = either; + +// =========================================================================== +using lex_dot_sep = sequence, character<'.'>, maybe>; + +using lex_unquoted_key = repeat, character<'_'>>, + at_least<1>>; +using lex_quoted_key = either; +using lex_simple_key = either; +using lex_dotted_key = sequence, + at_least<1> + > + >; +using lex_key = either; + +using lex_keyval_sep = sequence, + character<'='>, + maybe>; + +using lex_std_table_open = character<'['>; +using lex_std_table_close = character<']'>; +using lex_std_table = sequence, + lex_key, + maybe, + lex_std_table_close>; + +using lex_array_table_open = sequence; +using lex_array_table_close = sequence; +using lex_array_table = sequence, + lex_key, + maybe, + lex_array_table_close>; + +using lex_utf8_1byte = in_range<0x00, 0x7F>; +using lex_utf8_2byte = sequence< + in_range<'\xC2', '\xDF'>, + in_range<'\x80', '\xBF'> + >; +using lex_utf8_3byte = sequence, in_range<'\xA0', '\xBF'>>, + sequence, in_range<'\x80', '\xBF'>>, + sequence, in_range<'\x80', '\x9F'>>, + sequence, in_range<'\x80', '\xBF'>> + >, in_range<'\x80', '\xBF'>>; +using lex_utf8_4byte = sequence, in_range<'\x90', '\xBF'>>, + sequence, in_range<'\x80', '\xBF'>>, + sequence, in_range<'\x80', '\x8F'>> + >, in_range<'\x80', '\xBF'>, in_range<'\x80', '\xBF'>>; +using lex_utf8_code = either< + lex_utf8_1byte, + lex_utf8_2byte, + lex_utf8_3byte, + lex_utf8_4byte + >; + +using lex_comment_start_symbol = character<'#'>; +using lex_non_eol_ascii = either, in_range<0x20, 0x7E>>; +using lex_comment = sequence, unlimited>>; + +} // detail +} // toml +#endif // TOML_LEXER_HPP diff --git a/external/toml11/toml/literal.hpp b/external/toml11/toml/literal.hpp new file mode 100644 index 0000000..5086a76 --- /dev/null +++ b/external/toml11/toml/literal.hpp @@ -0,0 +1,113 @@ +// Copyright Toru Niina 2019. +// Distributed under the MIT License. +#ifndef TOML11_LITERAL_HPP +#define TOML11_LITERAL_HPP +#include "parser.hpp" + +namespace toml +{ +inline namespace literals +{ +inline namespace toml_literals +{ + +// implementation +inline ::toml::basic_value +literal_internal_impl(::toml::detail::location loc) +{ + using value_type = ::toml::basic_value< + TOML11_DEFAULT_COMMENT_STRATEGY, std::unordered_map, std::vector>; + // if there are some comments or empty lines, skip them. + using skip_line = ::toml::detail::repeat, + ::toml::detail::maybe<::toml::detail::lex_comment>, + ::toml::detail::lex_newline + >, ::toml::detail::at_least<1>>; + skip_line::invoke(loc); + + // if there are some whitespaces before a value, skip them. + using skip_ws = ::toml::detail::repeat< + ::toml::detail::lex_ws, ::toml::detail::at_least<1>>; + skip_ws::invoke(loc); + + // to distinguish arrays and tables, first check it is a table or not. + // + // "[1,2,3]"_toml; // this is an array + // "[table]"_toml; // a table that has an empty table named "table" inside. + // "[[1,2,3]]"_toml; // this is an array of arrays + // "[[table]]"_toml; // this is a table that has an array of tables inside. + // + // "[[1]]"_toml; // this can be both... (currently it becomes a table) + // "1 = [{}]"_toml; // this is a table that has an array of table named 1. + // "[[1,]]"_toml; // this is an array of arrays. + // "[[1],]"_toml; // this also. + + const auto the_front = loc.iter(); + + const bool is_table_key = ::toml::detail::lex_std_table::invoke(loc); + loc.reset(the_front); + + const bool is_aots_key = ::toml::detail::lex_array_table::invoke(loc); + loc.reset(the_front); + + // If it is neither a table-key or a array-of-table-key, it may be a value. + if(!is_table_key && !is_aots_key) + { + if(auto data = ::toml::detail::parse_value(loc, 0)) + { + return data.unwrap(); + } + } + + // Note that still it can be a table, because the literal might be something + // like the following. + // ```cpp + // R"( // c++11 raw string literals + // key = "value" + // int = 42 + // )"_toml; + // ``` + // It is a valid toml file. + // It should be parsed as if we parse a file with this content. + + if(auto data = ::toml::detail::parse_toml_file(loc)) + { + return data.unwrap(); + } + else // none of them. + { + throw ::toml::syntax_error(data.unwrap_err(), source_location(loc)); + } + +} + +inline ::toml::basic_value +operator"" _toml(const char* str, std::size_t len) +{ + ::toml::detail::location loc( + std::string("TOML literal encoded in a C++ code"), + std::vector(str, str + len)); + // literal length does not include the null character at the end. + return literal_internal_impl(std::move(loc)); +} + +// value of __cplusplus in C++2a/20 mode is not fixed yet along compilers. +// So here we use the feature test macro for `char8_t` itself. +#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L +// value of u8"" literal has been changed from char to char8_t and char8_t is +// NOT compatible to char +inline ::toml::basic_value +operator"" _toml(const char8_t* str, std::size_t len) +{ + ::toml::detail::location loc( + std::string("TOML literal encoded in a C++ code"), + std::vector(reinterpret_cast(str), + reinterpret_cast(str) + len)); + return literal_internal_impl(std::move(loc)); +} +#endif + +} // toml_literals +} // literals +} // toml +#endif//TOML11_LITERAL_HPP diff --git a/external/toml11/toml/macros.hpp b/external/toml11/toml/macros.hpp new file mode 100644 index 0000000..e8f91ae --- /dev/null +++ b/external/toml11/toml/macros.hpp @@ -0,0 +1,121 @@ +#ifndef TOML11_MACROS_HPP +#define TOML11_MACROS_HPP + +#define TOML11_STRINGIZE_AUX(x) #x +#define TOML11_STRINGIZE(x) TOML11_STRINGIZE_AUX(x) + +#define TOML11_CONCATENATE_AUX(x, y) x##y +#define TOML11_CONCATENATE(x, y) TOML11_CONCATENATE_AUX(x, y) + +// ============================================================================ +// TOML11_DEFINE_CONVERSION_NON_INTRUSIVE + +#ifndef TOML11_WITHOUT_DEFINE_NON_INTRUSIVE + +// ---------------------------------------------------------------------------- +// TOML11_ARGS_SIZE + +#define TOML11_INDEX_RSEQ() \ + 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, \ + 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 +#define TOML11_ARGS_SIZE_IMPL(\ + ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9, ARG10, \ + ARG11, ARG12, ARG13, ARG14, ARG15, ARG16, ARG17, ARG18, ARG19, ARG20, \ + ARG21, ARG22, ARG23, ARG24, ARG25, ARG26, ARG27, ARG28, ARG29, ARG30, \ + ARG31, ARG32, N, ...) N +#define TOML11_ARGS_SIZE_AUX(...) TOML11_ARGS_SIZE_IMPL(__VA_ARGS__) +#define TOML11_ARGS_SIZE(...) TOML11_ARGS_SIZE_AUX(__VA_ARGS__, TOML11_INDEX_RSEQ()) + +// ---------------------------------------------------------------------------- +// TOML11_FOR_EACH_VA_ARGS + +#define TOML11_FOR_EACH_VA_ARGS_AUX_1( FUNCTOR, ARG1 ) FUNCTOR(ARG1) +#define TOML11_FOR_EACH_VA_ARGS_AUX_2( FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_1( FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_3( FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_2( FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_4( FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_3( FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_5( FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_4( FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_6( FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_5( FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_7( FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_6( FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_8( FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_7( FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_9( FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_8( FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_10(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_9( FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_11(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_10(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_12(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_11(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_13(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_12(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_14(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_13(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_15(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_14(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_16(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_15(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_17(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_16(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_18(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_17(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_19(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_18(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_20(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_19(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_21(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_20(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_22(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_21(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_23(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_22(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_24(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_23(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_25(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_24(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_26(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_25(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_27(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_26(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_28(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_27(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_29(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_28(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_30(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_29(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_31(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_30(FUNCTOR, __VA_ARGS__) +#define TOML11_FOR_EACH_VA_ARGS_AUX_32(FUNCTOR, ARG1, ...) FUNCTOR(ARG1) TOML11_FOR_EACH_VA_ARGS_AUX_31(FUNCTOR, __VA_ARGS__) + +#define TOML11_FOR_EACH_VA_ARGS(FUNCTOR, ...)\ + TOML11_CONCATENATE(TOML11_FOR_EACH_VA_ARGS_AUX_, TOML11_ARGS_SIZE(__VA_ARGS__))(FUNCTOR, __VA_ARGS__) + +// ---------------------------------------------------------------------------- +// TOML11_DEFINE_CONVERSION_NON_INTRUSIVE + +// use it in the following way. +// ```cpp +// namespace foo +// { +// struct Foo +// { +// std::string s; +// double d; +// int i; +// }; +// } // foo +// +// TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(foo::Foo, s, d, i) +// ``` +// And then you can use `toml::find(file, "foo");` +// +#define TOML11_FIND_MEMBER_VARIABLE_FROM_VALUE(VAR_NAME)\ + obj.VAR_NAME = toml::find(v, TOML11_STRINGIZE(VAR_NAME)); + +#define TOML11_ASSIGN_MEMBER_VARIABLE_TO_VALUE(VAR_NAME)\ + v[TOML11_STRINGIZE(VAR_NAME)] = obj.VAR_NAME; + +#define TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(NAME, ...)\ + namespace toml { \ + template<> \ + struct from \ + { \ + template class T, \ + template class A> \ + static NAME from_toml(const basic_value& v) \ + { \ + NAME obj; \ + TOML11_FOR_EACH_VA_ARGS(TOML11_FIND_MEMBER_VARIABLE_FROM_VALUE, __VA_ARGS__) \ + return obj; \ + } \ + }; \ + template<> \ + struct into \ + { \ + static value into_toml(const NAME& obj) \ + { \ + ::toml::value v = ::toml::table{}; \ + TOML11_FOR_EACH_VA_ARGS(TOML11_ASSIGN_MEMBER_VARIABLE_TO_VALUE, __VA_ARGS__) \ + return v; \ + } \ + }; \ + } /* toml */ + +#endif// TOML11_WITHOUT_DEFINE_NON_INTRUSIVE + +#endif// TOML11_MACROS_HPP diff --git a/external/toml11/toml/parser.hpp b/external/toml11/toml/parser.hpp new file mode 100644 index 0000000..a8553dc --- /dev/null +++ b/external/toml11/toml/parser.hpp @@ -0,0 +1,2611 @@ +// Copyright Toru Niina 2017. +// Distributed under the MIT License. +#ifndef TOML11_PARSER_HPP +#define TOML11_PARSER_HPP +#include +#include +#include + +#include "combinator.hpp" +#include "lexer.hpp" +#include "macros.hpp" +#include "region.hpp" +#include "result.hpp" +#include "types.hpp" +#include "value.hpp" + +#ifndef TOML11_DISABLE_STD_FILESYSTEM +#ifdef __cpp_lib_filesystem +#if __has_include() +#define TOML11_HAS_STD_FILESYSTEM +#include +#endif // has_include() +#endif // __cpp_lib_filesystem +#endif // TOML11_DISABLE_STD_FILESYSTEM + +// the previous commit works with 500+ recursions. so it may be too small. +// but in most cases, i think we don't need such a deep recursion of +// arrays or inline-tables. +#define TOML11_VALUE_RECURSION_LIMIT 64 + +namespace toml +{ +namespace detail +{ + +inline result, std::string> +parse_boolean(location& loc) +{ + const auto first = loc.iter(); + if(const auto token = lex_boolean::invoke(loc)) + { + const auto reg = token.unwrap(); + if (reg.str() == "true") {return ok(std::make_pair(true, reg));} + else if(reg.str() == "false") {return ok(std::make_pair(false, reg));} + else // internal error. + { + throw internal_error(format_underline( + "toml::parse_boolean: internal error", + {{source_location(reg), "invalid token"}}), + source_location(reg)); + } + } + loc.reset(first); //rollback + return err(format_underline("toml::parse_boolean: ", + {{source_location(loc), "the next token is not a boolean"}})); +} + +inline result, std::string> +parse_binary_integer(location& loc) +{ + const auto first = loc.iter(); + if(const auto token = lex_bin_int::invoke(loc)) + { + auto str = token.unwrap().str(); + assert(str.size() > 2); // minimum -> 0b1 + assert(str.at(0) == '0' && str.at(1) == 'b'); + + // skip all the zeros and `_` locating at the MSB + str.erase(str.begin(), std::find_if( + str.begin() + 2, // to skip prefix `0b` + str.end(), + [](const char c) { return c == '1'; }) + ); + assert(str.empty() || str.front() == '1'); + + // since toml11 uses int64_t, 64bit (unsigned) input cannot be read. + const auto max_length = 63 + std::count(str.begin(), str.end(), '_'); + if(static_cast(max_length) < str.size()) + { + loc.reset(first); + return err(format_underline("toml::parse_binary_integer: " + "only signed 64bit integer is available", + {{source_location(loc), "too large input (> int64_t)"}})); + } + + integer retval(0), base(1); + for(auto i(str.rbegin()), e(str.rend()); i!=e; ++i) + { + assert(base != 0); // means overflow, checked in the above code + if(*i == '1') + { + retval += base; + if( (std::numeric_limits::max)() / 2 < base ) + { + base = 0; + } + base *= 2; + } + else if(*i == '0') + { + if( (std::numeric_limits::max)() / 2 < base ) + { + base = 0; + } + base *= 2; + } + else if(*i == '_') + { + // do nothing. + } + else // should be detected by lex_bin_int. [[unlikely]] + { + throw internal_error(format_underline( + "toml::parse_binary_integer: internal error", + {{source_location(token.unwrap()), "invalid token"}}), + source_location(loc)); + } + } + return ok(std::make_pair(retval, token.unwrap())); + } + loc.reset(first); + return err(format_underline("toml::parse_binary_integer:", + {{source_location(loc), "the next token is not an integer"}})); +} + +inline result, std::string> +parse_octal_integer(location& loc) +{ + const auto first = loc.iter(); + if(const auto token = lex_oct_int::invoke(loc)) + { + auto str = token.unwrap().str(); + str.erase(std::remove(str.begin(), str.end(), '_'), str.end()); + str.erase(str.begin()); str.erase(str.begin()); // remove `0o` prefix + + std::istringstream iss(str); + integer retval(0); + iss >> std::oct >> retval; + if(iss.fail()) + { + // `istream` sets `failbit` if internally-called `std::num_get::get` + // fails. + // `std::num_get::get` calls `std::strtoll` if the argument type is + // signed. + // `std::strtoll` fails if + // - the value is out_of_range or + // - no conversion is possible. + // since we already checked that the string is valid octal integer, + // so the error reason is out_of_range. + loc.reset(first); + return err(format_underline("toml::parse_octal_integer:", + {{source_location(loc), "out of range"}})); + } + return ok(std::make_pair(retval, token.unwrap())); + } + loc.reset(first); + return err(format_underline("toml::parse_octal_integer:", + {{source_location(loc), "the next token is not an integer"}})); +} + +inline result, std::string> +parse_hexadecimal_integer(location& loc) +{ + const auto first = loc.iter(); + if(const auto token = lex_hex_int::invoke(loc)) + { + auto str = token.unwrap().str(); + str.erase(std::remove(str.begin(), str.end(), '_'), str.end()); + str.erase(str.begin()); str.erase(str.begin()); // remove `0x` prefix + + std::istringstream iss(str); + integer retval(0); + iss >> std::hex >> retval; + if(iss.fail()) + { + // see parse_octal_integer for detail of this error message. + loc.reset(first); + return err(format_underline("toml::parse_hexadecimal_integer:", + {{source_location(loc), "out of range"}})); + } + return ok(std::make_pair(retval, token.unwrap())); + } + loc.reset(first); + return err(format_underline("toml::parse_hexadecimal_integer", + {{source_location(loc), "the next token is not an integer"}})); +} + +inline result, std::string> +parse_integer(location& loc) +{ + const auto first = loc.iter(); + if(first != loc.end() && *first == '0') + { + const auto second = std::next(first); + if(second == loc.end()) // the token is just zero. + { + loc.advance(); + return ok(std::make_pair(0, region(loc, first, second))); + } + + if(*second == 'b') {return parse_binary_integer (loc);} // 0b1100 + if(*second == 'o') {return parse_octal_integer (loc);} // 0o775 + if(*second == 'x') {return parse_hexadecimal_integer(loc);} // 0xC0FFEE + + if(std::isdigit(*second)) + { + return err(format_underline("toml::parse_integer: " + "leading zero in an Integer is not allowed.", + {{source_location(loc), "leading zero"}})); + } + else if(std::isalpha(*second)) + { + return err(format_underline("toml::parse_integer: " + "unknown integer prefix appeared.", + {{source_location(loc), "none of 0x, 0o, 0b"}})); + } + } + + if(const auto token = lex_dec_int::invoke(loc)) + { + auto str = token.unwrap().str(); + str.erase(std::remove(str.begin(), str.end(), '_'), str.end()); + + std::istringstream iss(str); + integer retval(0); + iss >> retval; + if(iss.fail()) + { + // see parse_octal_integer for detail of this error message. + loc.reset(first); + return err(format_underline("toml::parse_integer:", + {{source_location(loc), "out of range"}})); + } + return ok(std::make_pair(retval, token.unwrap())); + } + loc.reset(first); + return err(format_underline("toml::parse_integer: ", + {{source_location(loc), "the next token is not an integer"}})); +} + +inline result, std::string> +parse_floating(location& loc) +{ + const auto first = loc.iter(); + if(const auto token = lex_float::invoke(loc)) + { + auto str = token.unwrap().str(); + if(str == "inf" || str == "+inf") + { + if(std::numeric_limits::has_infinity) + { + return ok(std::make_pair( + std::numeric_limits::infinity(), token.unwrap())); + } + else + { + throw std::domain_error("toml::parse_floating: inf value found" + " but the current environment does not support inf. Please" + " make sure that the floating-point implementation conforms" + " IEEE 754/ISO 60559 international standard."); + } + } + else if(str == "-inf") + { + if(std::numeric_limits::has_infinity) + { + return ok(std::make_pair( + -std::numeric_limits::infinity(), token.unwrap())); + } + else + { + throw std::domain_error("toml::parse_floating: inf value found" + " but the current environment does not support inf. Please" + " make sure that the floating-point implementation conforms" + " IEEE 754/ISO 60559 international standard."); + } + } + else if(str == "nan" || str == "+nan") + { + if(std::numeric_limits::has_quiet_NaN) + { + return ok(std::make_pair( + std::numeric_limits::quiet_NaN(), token.unwrap())); + } + else if(std::numeric_limits::has_signaling_NaN) + { + return ok(std::make_pair( + std::numeric_limits::signaling_NaN(), token.unwrap())); + } + else + { + throw std::domain_error("toml::parse_floating: NaN value found" + " but the current environment does not support NaN. Please" + " make sure that the floating-point implementation conforms" + " IEEE 754/ISO 60559 international standard."); + } + } + else if(str == "-nan") + { + if(std::numeric_limits::has_quiet_NaN) + { + return ok(std::make_pair( + -std::numeric_limits::quiet_NaN(), token.unwrap())); + } + else if(std::numeric_limits::has_signaling_NaN) + { + return ok(std::make_pair( + -std::numeric_limits::signaling_NaN(), token.unwrap())); + } + else + { + throw std::domain_error("toml::parse_floating: NaN value found" + " but the current environment does not support NaN. Please" + " make sure that the floating-point implementation conforms" + " IEEE 754/ISO 60559 international standard."); + } + } + str.erase(std::remove(str.begin(), str.end(), '_'), str.end()); + std::istringstream iss(str); + floating v(0.0); + iss >> v; + if(iss.fail()) + { + // see parse_octal_integer for detail of this error message. + loc.reset(first); + return err(format_underline("toml::parse_floating:", + {{source_location(loc), "out of range"}})); + } + return ok(std::make_pair(v, token.unwrap())); + } + loc.reset(first); + return err(format_underline("toml::parse_floating: ", + {{source_location(loc), "the next token is not a float"}})); +} + +inline std::string read_utf8_codepoint(const region& reg, const location& loc) +{ + const auto str = reg.str().substr(1); + std::uint_least32_t codepoint; + std::istringstream iss(str); + iss >> std::hex >> codepoint; + + const auto to_char = [](const std::uint_least32_t i) noexcept -> char { + const auto uc = static_cast(i); + return *reinterpret_cast(std::addressof(uc)); + }; + + std::string character; + if(codepoint < 0x80) // U+0000 ... U+0079 ; just an ASCII. + { + character += static_cast(codepoint); + } + else if(codepoint < 0x800) //U+0080 ... U+07FF + { + // 110yyyyx 10xxxxxx; 0x3f == 0b0011'1111 + character += to_char(0xC0| codepoint >> 6); + character += to_char(0x80|(codepoint & 0x3F)); + } + else if(codepoint < 0x10000) // U+0800...U+FFFF + { + if(0xD800 <= codepoint && codepoint <= 0xDFFF) + { + throw syntax_error(format_underline( + "toml::read_utf8_codepoint: codepoints in the range " + "[0xD800, 0xDFFF] are not valid UTF-8.", {{ + source_location(loc), "not a valid UTF-8 codepoint" + }}), source_location(loc)); + } + assert(codepoint < 0xD800 || 0xDFFF < codepoint); + // 1110yyyy 10yxxxxx 10xxxxxx + character += to_char(0xE0| codepoint >> 12); + character += to_char(0x80|(codepoint >> 6 & 0x3F)); + character += to_char(0x80|(codepoint & 0x3F)); + } + else if(codepoint < 0x110000) // U+010000 ... U+10FFFF + { + // 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx + character += to_char(0xF0| codepoint >> 18); + character += to_char(0x80|(codepoint >> 12 & 0x3F)); + character += to_char(0x80|(codepoint >> 6 & 0x3F)); + character += to_char(0x80|(codepoint & 0x3F)); + } + else // out of UTF-8 region + { + throw syntax_error(format_underline("toml::read_utf8_codepoint:" + " input codepoint is too large.", + {{source_location(loc), "should be in [0x00..0x10FFFF]"}}), + source_location(loc)); + } + return character; +} + +inline result parse_escape_sequence(location& loc) +{ + const auto first = loc.iter(); + if(first == loc.end() || *first != '\\') + { + return err(format_underline("toml::parse_escape_sequence: ", {{ + source_location(loc), "the next token is not a backslash \"\\\""}})); + } + loc.advance(); + switch(*loc.iter()) + { + case '\\':{loc.advance(); return ok(std::string("\\"));} + case '"' :{loc.advance(); return ok(std::string("\""));} + case 'b' :{loc.advance(); return ok(std::string("\b"));} + case 't' :{loc.advance(); return ok(std::string("\t"));} + case 'n' :{loc.advance(); return ok(std::string("\n"));} + case 'f' :{loc.advance(); return ok(std::string("\f"));} + case 'r' :{loc.advance(); return ok(std::string("\r"));} +#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES + case 'e' :{loc.advance(); return ok(std::string("\x1b"));} // ESC +#endif + case 'u' : + { + if(const auto token = lex_escape_unicode_short::invoke(loc)) + { + return ok(read_utf8_codepoint(token.unwrap(), loc)); + } + else + { + return err(format_underline("parse_escape_sequence: " + "invalid token found in UTF-8 codepoint uXXXX.", + {{source_location(loc), "here"}})); + } + } + case 'U': + { + if(const auto token = lex_escape_unicode_long::invoke(loc)) + { + return ok(read_utf8_codepoint(token.unwrap(), loc)); + } + else + { + return err(format_underline("parse_escape_sequence: " + "invalid token found in UTF-8 codepoint Uxxxxxxxx", + {{source_location(loc), "here"}})); + } + } + } + + const auto msg = format_underline("parse_escape_sequence: " + "unknown escape sequence appeared.", {{source_location(loc), + "escape sequence is one of \\, \", b, t, n, f, r, uxxxx, Uxxxxxxxx"}}, + /* Hints = */{"if you want to write backslash as just one backslash, " + "use literal string like: regex = '<\\i\\c*\\s*>'"}); + loc.reset(first); + return err(msg); +} + +inline std::ptrdiff_t check_utf8_validity(const std::string& reg) +{ + location loc("tmp", reg); + const auto u8 = repeat::invoke(loc); + if(!u8 || loc.iter() != loc.end()) + { + const auto error_location = std::distance(loc.begin(), loc.iter()); + assert(0 <= error_location); + return error_location; + } + return -1; +} + +inline result, std::string> +parse_ml_basic_string(location& loc) +{ + const auto first = loc.iter(); + if(const auto token = lex_ml_basic_string::invoke(loc)) + { + auto inner_loc = loc; + inner_loc.reset(first); + + std::string retval; + retval.reserve(token.unwrap().size()); + + auto delim = lex_ml_basic_string_open::invoke(inner_loc); + if(!delim) + { + throw internal_error(format_underline( + "parse_ml_basic_string: invalid token", + {{source_location(inner_loc), "should be \"\"\""}}), + source_location(inner_loc)); + } + // immediate newline is ignored (if exists) + /* discard return value */ lex_newline::invoke(inner_loc); + + delim = none(); + while(!delim) + { + using lex_unescaped_seq = repeat< + either, unlimited>; + if(auto unescaped = lex_unescaped_seq::invoke(inner_loc)) + { + retval += unescaped.unwrap().str(); + } + if(auto escaped = parse_escape_sequence(inner_loc)) + { + retval += escaped.unwrap(); + } + if(auto esc_nl = lex_ml_basic_escaped_newline::invoke(inner_loc)) + { + // ignore newline after escape until next non-ws char + } + if(inner_loc.iter() == inner_loc.end()) + { + throw internal_error(format_underline( + "parse_ml_basic_string: unexpected end of region", + {{source_location(inner_loc), "not sufficient token"}}), + source_location(inner_loc)); + } + delim = lex_ml_basic_string_close::invoke(inner_loc); + } + // `lex_ml_basic_string_close` allows 3 to 5 `"`s to allow 1 or 2 `"`s + // at just before the delimiter. Here, we need to attach `"`s at the + // end of the string body, if it exists. + // For detail, see the definition of `lex_ml_basic_string_close`. + assert(std::all_of(delim.unwrap().first(), delim.unwrap().last(), + [](const char c) noexcept {return c == '\"';})); + switch(delim.unwrap().size()) + { + case 3: {break;} + case 4: {retval += "\""; break;} + case 5: {retval += "\"\""; break;} + default: + { + throw internal_error(format_underline( + "parse_ml_basic_string: closing delimiter has invalid length", + {{source_location(inner_loc), "end of this"}}), + source_location(inner_loc)); + } + } + + const auto err_loc = check_utf8_validity(token.unwrap().str()); + if(err_loc == -1) + { + return ok(std::make_pair(toml::string(retval), token.unwrap())); + } + else + { + inner_loc.reset(first); + inner_loc.advance(err_loc); + throw syntax_error(format_underline( + "parse_ml_basic_string: invalid utf8 sequence found", + {{source_location(inner_loc), "here"}}), + source_location(inner_loc)); + } + } + else + { + loc.reset(first); + return err(format_underline("toml::parse_ml_basic_string: " + "the next token is not a valid multiline string", + {{source_location(loc), "here"}})); + } +} + +inline result, std::string> +parse_basic_string(location& loc) +{ + const auto first = loc.iter(); + if(const auto token = lex_basic_string::invoke(loc)) + { + auto inner_loc = loc; + inner_loc.reset(first); + + auto quot = lex_quotation_mark::invoke(inner_loc); + if(!quot) + { + throw internal_error(format_underline("parse_basic_string: " + "invalid token", {{source_location(inner_loc), "should be \""}}), + source_location(inner_loc)); + } + + std::string retval; + retval.reserve(token.unwrap().size()); + + quot = none(); + while(!quot) + { + using lex_unescaped_seq = repeat; + if(auto unescaped = lex_unescaped_seq::invoke(inner_loc)) + { + retval += unescaped.unwrap().str(); + } + if(auto escaped = parse_escape_sequence(inner_loc)) + { + retval += escaped.unwrap(); + } + if(inner_loc.iter() == inner_loc.end()) + { + throw internal_error(format_underline( + "parse_basic_string: unexpected end of region", + {{source_location(inner_loc), "not sufficient token"}}), + source_location(inner_loc)); + } + quot = lex_quotation_mark::invoke(inner_loc); + } + + const auto err_loc = check_utf8_validity(token.unwrap().str()); + if(err_loc == -1) + { + return ok(std::make_pair(toml::string(retval), token.unwrap())); + } + else + { + inner_loc.reset(first); + inner_loc.advance(err_loc); + throw syntax_error(format_underline( + "parse_basic_string: invalid utf8 sequence found", + {{source_location(inner_loc), "here"}}), + source_location(inner_loc)); + } + } + else + { + loc.reset(first); // rollback + return err(format_underline("toml::parse_basic_string: " + "the next token is not a valid string", + {{source_location(loc), "here"}})); + } +} + +inline result, std::string> +parse_ml_literal_string(location& loc) +{ + const auto first = loc.iter(); + if(const auto token = lex_ml_literal_string::invoke(loc)) + { + auto inner_loc = loc; + inner_loc.reset(first); + + const auto open = lex_ml_literal_string_open::invoke(inner_loc); + if(!open) + { + throw internal_error(format_underline( + "parse_ml_literal_string: invalid token", + {{source_location(inner_loc), "should be '''"}}), + source_location(inner_loc)); + } + // immediate newline is ignored (if exists) + /* discard return value */ lex_newline::invoke(inner_loc); + + const auto body = lex_ml_literal_body::invoke(inner_loc); + + const auto close = lex_ml_literal_string_close::invoke(inner_loc); + if(!close) + { + throw internal_error(format_underline( + "parse_ml_literal_string: invalid token", + {{source_location(inner_loc), "should be '''"}}), + source_location(inner_loc)); + } + // `lex_ml_literal_string_close` allows 3 to 5 `'`s to allow 1 or 2 `'`s + // at just before the delimiter. Here, we need to attach `'`s at the + // end of the string body, if it exists. + // For detail, see the definition of `lex_ml_basic_string_close`. + + std::string retval = body.unwrap().str(); + assert(std::all_of(close.unwrap().first(), close.unwrap().last(), + [](const char c) noexcept {return c == '\'';})); + switch(close.unwrap().size()) + { + case 3: {break;} + case 4: {retval += "'"; break;} + case 5: {retval += "''"; break;} + default: + { + throw internal_error(format_underline( + "parse_ml_literal_string: closing delimiter has invalid length", + {{source_location(inner_loc), "end of this"}}), + source_location(inner_loc)); + } + } + + const auto err_loc = check_utf8_validity(token.unwrap().str()); + if(err_loc == -1) + { + return ok(std::make_pair(toml::string(retval, toml::string_t::literal), + token.unwrap())); + } + else + { + inner_loc.reset(first); + inner_loc.advance(err_loc); + throw syntax_error(format_underline( + "parse_ml_literal_string: invalid utf8 sequence found", + {{source_location(inner_loc), "here"}}), + source_location(inner_loc)); + } + } + else + { + loc.reset(first); // rollback + return err(format_underline("toml::parse_ml_literal_string: " + "the next token is not a valid multiline literal string", + {{source_location(loc), "here"}})); + } +} + +inline result, std::string> +parse_literal_string(location& loc) +{ + const auto first = loc.iter(); + if(const auto token = lex_literal_string::invoke(loc)) + { + auto inner_loc = loc; + inner_loc.reset(first); + + const auto open = lex_apostrophe::invoke(inner_loc); + if(!open) + { + throw internal_error(format_underline( + "parse_literal_string: invalid token", + {{source_location(inner_loc), "should be '"}}), + source_location(inner_loc)); + } + + const auto body = repeat::invoke(inner_loc); + + const auto close = lex_apostrophe::invoke(inner_loc); + if(!close) + { + throw internal_error(format_underline( + "parse_literal_string: invalid token", + {{source_location(inner_loc), "should be '"}}), + source_location(inner_loc)); + } + + const auto err_loc = check_utf8_validity(token.unwrap().str()); + if(err_loc == -1) + { + return ok(std::make_pair( + toml::string(body.unwrap().str(), toml::string_t::literal), + token.unwrap())); + } + else + { + inner_loc.reset(first); + inner_loc.advance(err_loc); + throw syntax_error(format_underline( + "parse_literal_string: invalid utf8 sequence found", + {{source_location(inner_loc), "here"}}), + source_location(inner_loc)); + } + } + else + { + loc.reset(first); // rollback + return err(format_underline("toml::parse_literal_string: " + "the next token is not a valid literal string", + {{source_location(loc), "here"}})); + } +} + +inline result, std::string> +parse_string(location& loc) +{ + if(loc.iter() != loc.end() && *(loc.iter()) == '"') + { + if(loc.iter() + 1 != loc.end() && *(loc.iter() + 1) == '"' && + loc.iter() + 2 != loc.end() && *(loc.iter() + 2) == '"') + { + return parse_ml_basic_string(loc); + } + else + { + return parse_basic_string(loc); + } + } + else if(loc.iter() != loc.end() && *(loc.iter()) == '\'') + { + if(loc.iter() + 1 != loc.end() && *(loc.iter() + 1) == '\'' && + loc.iter() + 2 != loc.end() && *(loc.iter() + 2) == '\'') + { + return parse_ml_literal_string(loc); + } + else + { + return parse_literal_string(loc); + } + } + return err(format_underline("toml::parse_string: ", + {{source_location(loc), "the next token is not a string"}})); +} + +inline result, std::string> +parse_local_date(location& loc) +{ + const auto first = loc.iter(); + if(const auto token = lex_local_date::invoke(loc)) + { + location inner_loc(loc.name(), token.unwrap().str()); + + const auto y = lex_date_fullyear::invoke(inner_loc); + if(!y || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != '-') + { + throw internal_error(format_underline( + "toml::parse_local_date: invalid year format", + {{source_location(inner_loc), "should be `-`"}}), + source_location(inner_loc)); + } + inner_loc.advance(); + const auto m = lex_date_month::invoke(inner_loc); + if(!m || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != '-') + { + throw internal_error(format_underline( + "toml::parse_local_date: invalid month format", + {{source_location(inner_loc), "should be `-`"}}), + source_location(inner_loc)); + } + inner_loc.advance(); + const auto d = lex_date_mday::invoke(inner_loc); + if(!d) + { + throw internal_error(format_underline( + "toml::parse_local_date: invalid day format", + {{source_location(inner_loc), "here"}}), + source_location(inner_loc)); + } + + const auto year = static_cast(from_string(y.unwrap().str(), 0)); + const auto month = static_cast(from_string(m.unwrap().str(), 0)); + const auto day = static_cast(from_string(d.unwrap().str(), 0)); + + // We briefly check whether the input date is valid or not. But here, we + // only check if the RFC3339 compliance. + // Actually there are several special date that does not exist, + // because of historical reasons, such as 1582/10/5-1582/10/14 (only in + // several countries). But here, we do not care about such a complicated + // rule. It makes the code complicated and there is only low probability + // that such a specific date is needed in practice. If someone need to + // validate date accurately, that means that the one need a specialized + // library for their purpose in a different layer. + { + const bool is_leap = (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)); + const auto max_day = (month == 2) ? (is_leap ? 29 : 28) : + ((month == 4 || month == 6 || month == 9 || month == 11) ? 30 : 31); + + if((month < 1 || 12 < month) || (day < 1 || max_day < day)) + { + throw syntax_error(format_underline("toml::parse_date: " + "invalid date: it does not conform RFC3339.", {{ + source_location(loc), "month should be 01-12, day should be" + " 01-28,29,30,31, depending on month/year." + }}), source_location(inner_loc)); + } + } + return ok(std::make_pair(local_date(year, static_cast(month - 1), day), + token.unwrap())); + } + else + { + loc.reset(first); + return err(format_underline("toml::parse_local_date: ", + {{source_location(loc), "the next token is not a local_date"}})); + } +} + +inline result, std::string> +parse_local_time(location& loc) +{ + const auto first = loc.iter(); + if(const auto token = lex_local_time::invoke(loc)) + { + location inner_loc(loc.name(), token.unwrap().str()); + + const auto h = lex_time_hour::invoke(inner_loc); + if(!h || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != ':') + { + throw internal_error(format_underline( + "toml::parse_local_time: invalid year format", + {{source_location(inner_loc), "should be `:`"}}), + source_location(inner_loc)); + } + inner_loc.advance(); + const auto m = lex_time_minute::invoke(inner_loc); + if(!m || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != ':') + { + throw internal_error(format_underline( + "toml::parse_local_time: invalid month format", + {{source_location(inner_loc), "should be `:`"}}), + source_location(inner_loc)); + } + inner_loc.advance(); + const auto s = lex_time_second::invoke(inner_loc); + if(!s) + { + throw internal_error(format_underline( + "toml::parse_local_time: invalid second format", + {{source_location(inner_loc), "here"}}), + source_location(inner_loc)); + } + + const int hour = from_string(h.unwrap().str(), 0); + const int minute = from_string(m.unwrap().str(), 0); + const int second = from_string(s.unwrap().str(), 0); + + if((hour < 0 || 23 < hour) || (minute < 0 || 59 < minute) || + (second < 0 || 60 < second)) // it may be leap second + { + throw syntax_error(format_underline("toml::parse_local_time: " + "invalid time: it does not conform RFC3339.", {{ + source_location(loc), "hour should be 00-23, minute should be" + " 00-59, second should be 00-60 (depending on the leap" + " second rules.)"}}), source_location(inner_loc)); + } + + local_time time(hour, minute, second, 0, 0); + + const auto before_secfrac = inner_loc.iter(); + if(const auto secfrac = lex_time_secfrac::invoke(inner_loc)) + { + auto sf = secfrac.unwrap().str(); + sf.erase(sf.begin()); // sf.front() == '.' + switch(sf.size() % 3) + { + case 2: sf += '0'; break; + case 1: sf += "00"; break; + case 0: break; + default: break; + } + if(sf.size() >= 9) + { + time.millisecond = from_string(sf.substr(0, 3), 0u); + time.microsecond = from_string(sf.substr(3, 3), 0u); + time.nanosecond = from_string(sf.substr(6, 3), 0u); + } + else if(sf.size() >= 6) + { + time.millisecond = from_string(sf.substr(0, 3), 0u); + time.microsecond = from_string(sf.substr(3, 3), 0u); + } + else if(sf.size() >= 3) + { + time.millisecond = from_string(sf, 0u); + time.microsecond = 0u; + } + } + else + { + if(before_secfrac != inner_loc.iter()) + { + throw internal_error(format_underline( + "toml::parse_local_time: invalid subsecond format", + {{source_location(inner_loc), "here"}}), + source_location(inner_loc)); + } + } + return ok(std::make_pair(time, token.unwrap())); + } + else + { + loc.reset(first); + return err(format_underline("toml::parse_local_time: ", + {{source_location(loc), "the next token is not a local_time"}})); + } +} + +inline result, std::string> +parse_local_datetime(location& loc) +{ + const auto first = loc.iter(); + if(const auto token = lex_local_date_time::invoke(loc)) + { + location inner_loc(loc.name(), token.unwrap().str()); + const auto date = parse_local_date(inner_loc); + if(!date || inner_loc.iter() == inner_loc.end()) + { + throw internal_error(format_underline( + "toml::parse_local_datetime: invalid datetime format", + {{source_location(inner_loc), "date, not datetime"}}), + source_location(inner_loc)); + } + const char delim = *(inner_loc.iter()); + if(delim != 'T' && delim != 't' && delim != ' ') + { + throw internal_error(format_underline( + "toml::parse_local_datetime: invalid datetime format", + {{source_location(inner_loc), "should be `T` or ` ` (space)"}}), + source_location(inner_loc)); + } + inner_loc.advance(); + const auto time = parse_local_time(inner_loc); + if(!time) + { + throw internal_error(format_underline( + "toml::parse_local_datetime: invalid datetime format", + {{source_location(inner_loc), "invalid time format"}}), + source_location(inner_loc)); + } + return ok(std::make_pair( + local_datetime(date.unwrap().first, time.unwrap().first), + token.unwrap())); + } + else + { + loc.reset(first); + return err(format_underline("toml::parse_local_datetime: ", + {{source_location(loc), "the next token is not a local_datetime"}})); + } +} + +inline result, std::string> +parse_offset_datetime(location& loc) +{ + const auto first = loc.iter(); + if(const auto token = lex_offset_date_time::invoke(loc)) + { + location inner_loc(loc.name(), token.unwrap().str()); + const auto datetime = parse_local_datetime(inner_loc); + if(!datetime || inner_loc.iter() == inner_loc.end()) + { + throw internal_error(format_underline( + "toml::parse_offset_datetime: invalid datetime format", + {{source_location(inner_loc), "date, not datetime"}}), + source_location(inner_loc)); + } + time_offset offset(0, 0); + if(const auto ofs = lex_time_numoffset::invoke(inner_loc)) + { + const auto str = ofs.unwrap().str(); + + const auto hour = from_string(str.substr(1,2), 0); + const auto minute = from_string(str.substr(4,2), 0); + + if((hour < 0 || 23 < hour) || (minute < 0 || 59 < minute)) + { + throw syntax_error(format_underline("toml::parse_offset_datetime: " + "invalid offset: it does not conform RFC3339.", {{ + source_location(loc), "month should be 01-12, day should be" + " 01-28,29,30,31, depending on month/year." + }}), source_location(inner_loc)); + } + + if(str.front() == '+') + { + offset = time_offset(hour, minute); + } + else + { + offset = time_offset(-hour, -minute); + } + } + else if(*inner_loc.iter() != 'Z' && *inner_loc.iter() != 'z') + { + throw internal_error(format_underline( + "toml::parse_offset_datetime: invalid datetime format", + {{source_location(inner_loc), "should be `Z` or `+HH:MM`"}}), + source_location(inner_loc)); + } + return ok(std::make_pair(offset_datetime(datetime.unwrap().first, offset), + token.unwrap())); + } + else + { + loc.reset(first); + return err(format_underline("toml::parse_offset_datetime: ", + {{source_location(loc), "the next token is not a offset_datetime"}})); + } +} + +inline result, std::string> +parse_simple_key(location& loc) +{ + if(const auto bstr = parse_basic_string(loc)) + { + return ok(std::make_pair(bstr.unwrap().first.str, bstr.unwrap().second)); + } + if(const auto lstr = parse_literal_string(loc)) + { + return ok(std::make_pair(lstr.unwrap().first.str, lstr.unwrap().second)); + } + if(const auto bare = lex_unquoted_key::invoke(loc)) + { + const auto reg = bare.unwrap(); + return ok(std::make_pair(reg.str(), reg)); + } + return err(format_underline("toml::parse_simple_key: ", + {{source_location(loc), "the next token is not a simple key"}})); +} + +// dotted key become vector of keys +inline result, region>, std::string> +parse_key(location& loc) +{ + const auto first = loc.iter(); + // dotted key -> `foo.bar.baz` where several single keys are chained by + // dots. Whitespaces between keys and dots are allowed. + if(const auto token = lex_dotted_key::invoke(loc)) + { + const auto reg = token.unwrap(); + location inner_loc(loc.name(), reg.str()); + std::vector keys; + + while(inner_loc.iter() != inner_loc.end()) + { + lex_ws::invoke(inner_loc); + if(const auto k = parse_simple_key(inner_loc)) + { + keys.push_back(k.unwrap().first); + } + else + { + throw internal_error(format_underline( + "toml::parse_key: dotted key contains invalid key", + {{source_location(inner_loc), k.unwrap_err()}}), + source_location(inner_loc)); + } + + lex_ws::invoke(inner_loc); + if(inner_loc.iter() == inner_loc.end()) + { + break; + } + else if(*inner_loc.iter() == '.') + { + inner_loc.advance(); // to skip `.` + } + else + { + throw internal_error(format_underline("toml::parse_key: " + "dotted key contains invalid key ", + {{source_location(inner_loc), "should be `.`"}}), + source_location(inner_loc)); + } + } + return ok(std::make_pair(keys, reg)); + } + loc.reset(first); + + // simple_key: a single (basic_string|literal_string|bare key) + if(const auto smpl = parse_simple_key(loc)) + { + return ok(std::make_pair(std::vector(1, smpl.unwrap().first), + smpl.unwrap().second)); + } + return err(format_underline("toml::parse_key: an invalid key appeared.", + {{source_location(loc), "is not a valid key"}}, { + "bare keys : non-empty strings composed only of [A-Za-z0-9_-].", + "quoted keys: same as \"basic strings\" or 'literal strings'.", + "dotted keys: sequence of bare or quoted keys joined with a dot." + })); +} + +// forward-decl to implement parse_array and parse_table +template +result parse_value(location&, const std::size_t n_rec); + +template +result, std::string> +parse_array(location& loc, const std::size_t n_rec) +{ + using value_type = Value; + using array_type = typename value_type::array_type; + + if(n_rec > TOML11_VALUE_RECURSION_LIMIT) + { + // parse_array does not have any way to handle recursive error currently... + throw syntax_error(std::string("toml::parse_array: recursion limit (" + TOML11_STRINGIZE(TOML11_VALUE_RECURSION_LIMIT) ") exceeded"), + source_location(loc)); + } + + const auto first = loc.iter(); + if(loc.iter() == loc.end()) + { + return err("toml::parse_array: input is empty"); + } + if(*loc.iter() != '[') + { + return err("toml::parse_array: token is not an array"); + } + loc.advance(); + + using lex_ws_comment_newline = repeat< + either, unlimited>; + + array_type retval; + while(loc.iter() != loc.end()) + { + lex_ws_comment_newline::invoke(loc); // skip + + if(loc.iter() != loc.end() && *loc.iter() == ']') + { + loc.advance(); // skip ']' + return ok(std::make_pair(retval, + region(loc, first, loc.iter()))); + } + + if(auto val = parse_value(loc, n_rec+1)) + { + // After TOML v1.0.0-rc.1, array becomes to be able to have values + // with different types. So here we will omit this by default. + // + // But some of the test-suite checks if the parser accepts a hetero- + // geneous arrays, so we keep this for a while. +#ifdef TOML11_DISALLOW_HETEROGENEOUS_ARRAYS + if(!retval.empty() && retval.front().type() != val.as_ok().type()) + { + auto array_start_loc = loc; + array_start_loc.reset(first); + + throw syntax_error(format_underline("toml::parse_array: " + "type of elements should be the same each other.", { + {source_location(array_start_loc), "array starts here"}, + { + retval.front().location(), + "value has type " + stringize(retval.front().type()) + }, + { + val.unwrap().location(), + "value has different type, " + stringize(val.unwrap().type()) + } + }), source_location(loc)); + } +#endif + retval.push_back(std::move(val.unwrap())); + } + else + { + auto array_start_loc = loc; + array_start_loc.reset(first); + + throw syntax_error(format_underline("toml::parse_array: " + "value having invalid format appeared in an array", { + {source_location(array_start_loc), "array starts here"}, + {source_location(loc), "it is not a valid value."} + }), source_location(loc)); + } + + using lex_array_separator = sequence, character<','>>; + const auto sp = lex_array_separator::invoke(loc); + if(!sp) + { + lex_ws_comment_newline::invoke(loc); + if(loc.iter() != loc.end() && *loc.iter() == ']') + { + loc.advance(); // skip ']' + return ok(std::make_pair(retval, + region(loc, first, loc.iter()))); + } + else + { + auto array_start_loc = loc; + array_start_loc.reset(first); + + throw syntax_error(format_underline("toml::parse_array:" + " missing array separator `,` after a value", { + {source_location(array_start_loc), "array starts here"}, + {source_location(loc), "should be `,`"} + }), source_location(loc)); + } + } + } + loc.reset(first); + throw syntax_error(format_underline("toml::parse_array: " + "array did not closed by `]`", + {{source_location(loc), "should be closed"}}), + source_location(loc)); +} + +template +result, region>, Value>, std::string> +parse_key_value_pair(location& loc, const std::size_t n_rec) +{ + using value_type = Value; + + const auto first = loc.iter(); + auto key_reg = parse_key(loc); + if(!key_reg) + { + std::string msg = std::move(key_reg.unwrap_err()); + // if the next token is keyvalue-separator, it means that there are no + // key. then we need to show error as "empty key is not allowed". + if(const auto keyval_sep = lex_keyval_sep::invoke(loc)) + { + loc.reset(first); + msg = format_underline("toml::parse_key_value_pair: " + "empty key is not allowed.", + {{source_location(loc), "key expected before '='"}}); + } + return err(std::move(msg)); + } + + const auto kvsp = lex_keyval_sep::invoke(loc); + if(!kvsp) + { + std::string msg; + // if the line contains '=' after the invalid sequence, possibly the + // error is in the key (like, invalid character in bare key). + const auto line_end = std::find(loc.iter(), loc.end(), '\n'); + if(std::find(loc.iter(), line_end, '=') != line_end) + { + msg = format_underline("toml::parse_key_value_pair: " + "invalid format for key", + {{source_location(loc), "invalid character in key"}}, + {"Did you forget '.' to separate dotted-key?", + "Allowed characters for bare key are [0-9a-zA-Z_-]."}); + } + else // if not, the error is lack of key-value separator. + { + msg = format_underline("toml::parse_key_value_pair: " + "missing key-value separator `=`", + {{source_location(loc), "should be `=`"}}); + } + loc.reset(first); + return err(std::move(msg)); + } + + const auto after_kvsp = loc.iter(); // err msg + auto val = parse_value(loc, n_rec); + if(!val) + { + std::string msg; + loc.reset(after_kvsp); + // check there is something not a comment/whitespace after `=` + if(sequence, maybe, lex_newline>::invoke(loc)) + { + loc.reset(after_kvsp); + msg = format_underline("toml::parse_key_value_pair: " + "missing value after key-value separator '='", + {{source_location(loc), "expected value, but got nothing"}}); + } + else // there is something not a comment/whitespace, so invalid format. + { + msg = std::move(val.unwrap_err()); + } + loc.reset(first); + return err(msg); + } + return ok(std::make_pair(std::move(key_reg.unwrap()), + std::move(val.unwrap()))); +} + +// for error messages. +template +std::string format_dotted_keys(InputIterator first, const InputIterator last) +{ + static_assert(std::is_same::value_type>::value,""); + + std::string retval(*first++); + for(; first != last; ++first) + { + retval += '.'; + retval += *first; + } + return retval; +} + +// forward decl for is_valid_forward_table_definition +result, region>, std::string> +parse_table_key(location& loc); +result, region>, std::string> +parse_array_table_key(location& loc); +template +result, std::string> +parse_inline_table(location& loc, const std::size_t n_rec); + +// The following toml file is allowed. +// ```toml +// [a.b.c] # here, table `a` has element `b`. +// foo = "bar" +// [a] # merge a = {baz = "qux"} to a = {b = {...}} +// baz = "qux" +// ``` +// But the following is not allowed. +// ```toml +// [a] +// b.c.foo = "bar" +// [a] # error! the same table [a] defined! +// baz = "qux" +// ``` +// The following is neither allowed. +// ```toml +// a = { b.c.foo = "bar"} +// [a] # error! the same table [a] defined! +// baz = "qux" +// ``` +// Here, it parses region of `tab->at(k)` as a table key and check the depth +// of the key. If the key region points deeper node, it would be allowed. +// Otherwise, the key points the same node. It would be rejected. +template +bool is_valid_forward_table_definition(const Value& fwd, const Value& inserting, + Iterator key_first, Iterator key_curr, Iterator key_last) +{ + // ------------------------------------------------------------------------ + // check type of the value to be inserted/merged + + std::string inserting_reg = ""; + if(const auto ptr = detail::get_region(inserting)) + { + inserting_reg = ptr->str(); + } + location inserting_def("internal", std::move(inserting_reg)); + if(const auto inlinetable = parse_inline_table(inserting_def, 0)) + { + // check if we are overwriting existing table. + // ```toml + // # NG + // a.b = 42 + // a = {d = 3.14} + // ``` + // Inserting an inline table to a existing super-table is not allowed in + // any case. If we found it, we can reject it without further checking. + return false; + } + + // Valid and invalid cases when inserting to the [a.b] table: + // + // ## Invalid + // + // ```toml + // # invalid + // [a] + // b.c.d = "foo" + // [a.b] # a.b is already defined and closed + // d = "bar" + // ``` + // ```toml + // # invalid + // a = {b.c.d = "foo"} + // [a.b] # a is already defined and inline table is closed + // d = "bar" + // ``` + // ```toml + // # invalid + // a.b.c.d = "foo" + // [a.b] # a.b is already defined and dotted-key table is closed + // d = "bar" + // ``` + // + // ## Valid + // + // ```toml + // # OK. a.b is defined, but is *overwritable* + // [a.b.c] + // d = "foo" + // [a.b] + // d = "bar" + // ``` + // ```toml + // # OK. a.b is defined, but is *overwritable* + // [a] + // b.c.d = "foo" + // b.e = "bar" + // ``` + + // ------------------------------------------------------------------------ + // check table defined before + + std::string internal = ""; + if(const auto ptr = detail::get_region(fwd)) + { + internal = ptr->str(); + } + location def("internal", std::move(internal)); + if(const auto tabkeys = parse_table_key(def)) // [table.key] + { + // table keys always contains all the nodes from the root. + const auto& tks = tabkeys.unwrap().first; + if(std::size_t(std::distance(key_first, key_last)) == tks.size() && + std::equal(tks.begin(), tks.end(), key_first)) + { + // the keys are equivalent. it is not allowed. + return false; + } + // the keys are not equivalent. it is allowed. + return true; + } + // nested array-of-table definition implicitly defines tables. + // those tables can be reopened. + if(const auto atabkeys = parse_array_table_key(def)) + { + // table keys always contains all the nodes from the root. + const auto& tks = atabkeys.unwrap().first; + if(std::size_t(std::distance(key_first, key_last)) == tks.size() && + std::equal(tks.begin(), tks.end(), key_first)) + { + // the keys are equivalent. it is not allowed. + return false; + } + // the keys are not equivalent. it is allowed. + return true; + } + if(const auto dotkeys = parse_key(def)) // a.b.c = "foo" + { + // consider the following case. + // [a] + // b.c = {d = 42} + // [a.b.c] + // e = 2.71 + // this defines the table [a.b.c] twice. no? + if(const auto reopening_dotkey_by_table = parse_table_key(inserting_def)) + { + // re-opening a dotkey-defined table by a table is invalid. + // only dotkey can append a key-val. Like: + // ```toml + // a.b.c = "foo" + // a.b.d = "bar" # OK. reopen `a.b` by dotkey + // [a.b] + // e = "bar" # Invalid. re-opening `a.b` by [a.b] is not allowed. + // ``` + return false; + } + + // a dotted key starts from the node representing a table in which the + // dotted key belongs to. + const auto& dks = dotkeys.unwrap().first; + if(std::size_t(std::distance(key_curr, key_last)) == dks.size() && + std::equal(dks.begin(), dks.end(), key_curr)) + { + // the keys are equivalent. it is not allowed. + return false; + } + // the keys are not equivalent. it is allowed. + return true; + } + return false; +} + +template +result +insert_nested_key(typename Value::table_type& root, const Value& v, + InputIterator iter, const InputIterator last, + region key_reg, + const bool is_array_of_table = false) +{ + static_assert(std::is_same::value_type>::value,""); + + using value_type = Value; + using table_type = typename value_type::table_type; + using array_type = typename value_type::array_type; + + const auto first = iter; + assert(iter != last); + + table_type* tab = std::addressof(root); + for(; iter != last; ++iter) // search recursively + { + const key& k = *iter; + if(std::next(iter) == last) // k is the last key + { + // XXX if the value is array-of-tables, there can be several + // tables that are in the same array. in that case, we need to + // find the last element and insert it to there. + if(is_array_of_table) + { + if(tab->count(k) == 1) // there is already an array of table + { + if(tab->at(k).is_table()) + { + // show special err msg for conflicting table + throw syntax_error(format_underline(concat_to_string( + "toml::insert_value: array of table (\"", + format_dotted_keys(first, last), + "\") cannot be defined"), { + {tab->at(k).location(), "table already defined"}, + {v.location(), "this conflicts with the previous table"} + }), v.location()); + } + else if(!(tab->at(k).is_array())) + { + throw syntax_error(format_underline(concat_to_string( + "toml::insert_value: array of table (\"", + format_dotted_keys(first, last), "\") collides with" + " existing value"), { + {tab->at(k).location(), + concat_to_string("this ", tab->at(k).type(), + " value already exists")}, + {v.location(), + "while inserting this array-of-tables"} + }), v.location()); + } + // the above if-else-if checks tab->at(k) is an array + auto& a = tab->at(k).as_array(); + // If table element is defined as [[array_of_tables]], it + // cannot be an empty array. If an array of tables is + // defined as `aot = []`, it cannot be appended. + if(a.empty() || !(a.front().is_table())) + { + throw syntax_error(format_underline(concat_to_string( + "toml::insert_value: array of table (\"", + format_dotted_keys(first, last), "\") collides with" + " existing value"), { + {tab->at(k).location(), + concat_to_string("this ", tab->at(k).type(), + " value already exists")}, + {v.location(), + "while inserting this array-of-tables"} + }), v.location()); + } + // avoid conflicting array of table like the following. + // ```toml + // a = [{b = 42}] # define a as an array of *inline* tables + // [[a]] # a is an array of *multi-line* tables + // b = 54 + // ``` + // Here, from the type information, these cannot be detected + // because inline table is also a table. + // But toml v0.5.0 explicitly says it is invalid. The above + // array-of-tables has a static size and appending to the + // array is invalid. + // In this library, multi-line table value has a region + // that points to the key of the table (e.g. [[a]]). By + // comparing the first two letters in key, we can detect + // the array-of-table is inline or multiline. + if(const auto ptr = detail::get_region(a.front())) + { + if(ptr->str().substr(0,2) != "[[") + { + throw syntax_error(format_underline(concat_to_string( + "toml::insert_value: array of table (\"", + format_dotted_keys(first, last), "\") collides " + "with existing array-of-tables"), { + {tab->at(k).location(), + concat_to_string("this ", tab->at(k).type(), + " value has static size")}, + {v.location(), + "appending it to the statically sized array"} + }), v.location()); + } + } + a.push_back(v); + return ok(true); + } + else // if not, we need to create the array of table + { + // XXX: Consider the following array of tables. + // ```toml + // # This is a comment. + // [[aot]] + // foo = "bar" + // ``` + // Here, the comment is for `aot`. But here, actually two + // values are defined. An array that contains tables, named + // `aot`, and the 0th element of the `aot`, `{foo = "bar"}`. + // Those two are different from each other. But both of them + // points to the same portion of the TOML file, `[[aot]]`, + // so `key_reg.comments()` returns `# This is a comment`. + // If it is assigned as a comment of `aot` defined here, the + // comment will be duplicated. Both the `aot` itself and + // the 0-th element will have the same comment. This causes + // "duplication of the same comments" bug when the data is + // serialized. + // Next, consider the following. + // ```toml + // # comment 1 + // aot = [ + // # comment 2 + // {foo = "bar"}, + // ] + // ``` + // In this case, we can distinguish those two comments. So + // here we need to add "comment 1" to the `aot` and + // "comment 2" to the 0th element of that. + // To distinguish those two, we check the key region. + std::vector comments{/* empty by default */}; + if(key_reg.str().substr(0, 2) != "[[") + { + comments = key_reg.comments(); + } + value_type aot(array_type(1, v), key_reg, std::move(comments)); + tab->insert(std::make_pair(k, aot)); + return ok(true); + } + } // end if(array of table) + + if(tab->count(k) == 1) + { + if(tab->at(k).is_table() && v.is_table()) + { + if(!is_valid_forward_table_definition( + tab->at(k), v, first, iter, last)) + { + throw syntax_error(format_underline(concat_to_string( + "toml::insert_value: table (\"", + format_dotted_keys(first, last), + "\") already exists."), { + {tab->at(k).location(), "table already exists here"}, + {v.location(), "table defined twice"} + }), v.location()); + } + // to allow the following toml file. + // [a.b.c] + // d = 42 + // [a] + // e = 2.71 + auto& t = tab->at(k).as_table(); + for(const auto& kv : v.as_table()) + { + if(tab->at(k).contains(kv.first)) + { + throw syntax_error(format_underline(concat_to_string( + "toml::insert_value: value (\"", + format_dotted_keys(first, last), + "\") already exists."), { + {t.at(kv.first).location(), "already exists here"}, + {v.location(), "this defined twice"} + }), v.location()); + } + t[kv.first] = kv.second; + } + detail::change_region(tab->at(k), key_reg); + return ok(true); + } + else if(v.is_table() && + tab->at(k).is_array() && + tab->at(k).as_array().size() > 0 && + tab->at(k).as_array().front().is_table()) + { + throw syntax_error(format_underline(concat_to_string( + "toml::insert_value: array of tables (\"", + format_dotted_keys(first, last), "\") already exists."), { + {tab->at(k).location(), "array of tables defined here"}, + {v.location(), "table conflicts with the previous array of table"} + }), v.location()); + } + else + { + throw syntax_error(format_underline(concat_to_string( + "toml::insert_value: value (\"", + format_dotted_keys(first, last), "\") already exists."), { + {tab->at(k).location(), "value already exists here"}, + {v.location(), "value defined twice"} + }), v.location()); + } + } + tab->insert(std::make_pair(k, v)); + return ok(true); + } + else // k is not the last one, we should insert recursively + { + // if there is no corresponding value, insert it first. + // related: you don't need to write + // # [x] + // # [x.y] + // to write + // [x.y.z] + if(tab->count(k) == 0) + { + // a table that is defined implicitly doesn't have any comments. + (*tab)[k] = value_type(table_type{}, key_reg, {/*no comment*/}); + } + + // type checking... + if(tab->at(k).is_table()) + { + // According to toml-lang/toml:36d3091b3 "Clarify that inline + // tables are immutable", check if it adds key-value pair to an + // inline table. + if(const auto* ptr = get_region(tab->at(k))) + { + // here, if the value is a (multi-line) table, the region + // should be something like `[table-name]`. + if(ptr->front() == '{') + { + throw syntax_error(format_underline(concat_to_string( + "toml::insert_value: inserting to an inline table (", + format_dotted_keys(first, std::next(iter)), + ") but inline tables are immutable"), { + {tab->at(k).location(), "inline tables are immutable"}, + {v.location(), "inserting this"} + }), v.location()); + } + } + tab = std::addressof((*tab)[k].as_table()); + } + else if(tab->at(k).is_array()) // inserting to array-of-tables? + { + auto& a = (*tab)[k].as_array(); + if(!a.back().is_table()) + { + throw syntax_error(format_underline(concat_to_string( + "toml::insert_value: target (", + format_dotted_keys(first, std::next(iter)), + ") is neither table nor an array of tables"), { + {a.back().location(), concat_to_string( + "actual type is ", a.back().type())}, + {v.location(), "inserting this"} + }), v.location()); + } + if(a.empty()) + { + throw syntax_error(format_underline(concat_to_string( + "toml::insert_value: table (\"", + format_dotted_keys(first, last), "\") conflicts with" + " existing value"), { + {tab->at(k).location(), std::string("this array is not insertable")}, + {v.location(), std::string("appending it to the statically sized array")} + }), v.location()); + } + if(const auto ptr = detail::get_region(a.at(0))) + { + if(ptr->str().substr(0,2) != "[[") + { + throw syntax_error(format_underline(concat_to_string( + "toml::insert_value: a table (\"", + format_dotted_keys(first, last), "\") cannot be " + "inserted to an existing inline array-of-tables"), { + {tab->at(k).location(), std::string("this array of table has a static size")}, + {v.location(), std::string("appending it to the statically sized array")} + }), v.location()); + } + } + tab = std::addressof(a.back().as_table()); + } + else + { + throw syntax_error(format_underline(concat_to_string( + "toml::insert_value: target (", + format_dotted_keys(first, std::next(iter)), + ") is neither table nor an array of tables"), { + {tab->at(k).location(), concat_to_string( + "actual type is ", tab->at(k).type())}, + {v.location(), "inserting this"} + }), v.location()); + } + } + } + return err(std::string("toml::detail::insert_nested_key: never reach here")); +} + +template +result, std::string> +parse_inline_table(location& loc, const std::size_t n_rec) +{ + using value_type = Value; + using table_type = typename value_type::table_type; + + if(n_rec > TOML11_VALUE_RECURSION_LIMIT) + { + throw syntax_error(std::string("toml::parse_inline_table: recursion limit (" + TOML11_STRINGIZE(TOML11_VALUE_RECURSION_LIMIT) ") exceeded"), + source_location(loc)); + } + + const auto first = loc.iter(); + table_type retval; + if(!(loc.iter() != loc.end() && *loc.iter() == '{')) + { + return err(format_underline("toml::parse_inline_table: ", + {{source_location(loc), "the next token is not an inline table"}})); + } + loc.advance(); + + // check if the inline table is an empty table = { } + maybe::invoke(loc); + if(loc.iter() != loc.end() && *loc.iter() == '}') + { + loc.advance(); // skip `}` + return ok(std::make_pair(retval, region(loc, first, loc.iter()))); + } + + // it starts from "{". it should be formatted as inline-table + while(loc.iter() != loc.end()) + { + const auto kv_r = parse_key_value_pair(loc, n_rec+1); + if(!kv_r) + { + return err(kv_r.unwrap_err()); + } + + const auto& kvpair = kv_r.unwrap(); + const std::vector& keys = kvpair.first.first; + const auto& key_reg = kvpair.first.second; + const value_type& val = kvpair.second; + + const auto inserted = + insert_nested_key(retval, val, keys.begin(), keys.end(), key_reg); + if(!inserted) + { + throw internal_error("toml::parse_inline_table: " + "failed to insert value into table: " + inserted.unwrap_err(), + source_location(loc)); + } + + using lex_table_separator = sequence, character<','>>; + const auto sp = lex_table_separator::invoke(loc); + + if(!sp) + { + maybe::invoke(loc); + + if(loc.iter() == loc.end()) + { + throw syntax_error(format_underline( + "toml::parse_inline_table: missing table separator `}` ", + {{source_location(loc), "should be `}`"}}), + source_location(loc)); + } + else if(*loc.iter() == '}') + { + loc.advance(); // skip `}` + return ok(std::make_pair( + retval, region(loc, first, loc.iter()))); + } + else if(*loc.iter() == '#' || *loc.iter() == '\r' || *loc.iter() == '\n') + { + throw syntax_error(format_underline( + "toml::parse_inline_table: missing curly brace `}`", + {{source_location(loc), "should be `}`"}}), + source_location(loc)); + } + else + { + throw syntax_error(format_underline( + "toml::parse_inline_table: missing table separator `,` ", + {{source_location(loc), "should be `,`"}}), + source_location(loc)); + } + } + else // `,` is found + { + maybe::invoke(loc); + if(loc.iter() != loc.end() && *loc.iter() == '}') + { + throw syntax_error(format_underline( + "toml::parse_inline_table: trailing comma is not allowed in" + " an inline table", + {{source_location(loc), "should be `}`"}}), + source_location(loc)); + } + } + } + loc.reset(first); + throw syntax_error(format_underline("toml::parse_inline_table: " + "inline table did not closed by `}`", + {{source_location(loc), "should be closed"}}), + source_location(loc)); +} + +inline result guess_number_type(const location& l) +{ + // This function tries to find some (common) mistakes by checking characters + // that follows the last character of a value. But it is often difficult + // because some non-newline characters can appear after a value. E.g. + // spaces, tabs, commas (in an array or inline table), closing brackets + // (of an array or inline table), comment-sign (#). Since this function + // does not parse further, those characters are always allowed to be there. + location loc = l; + + if(lex_offset_date_time::invoke(loc)) {return ok(value_t::offset_datetime);} + loc.reset(l.iter()); + + if(lex_local_date_time::invoke(loc)) + { + // bad offset may appear after this. + if(loc.iter() != loc.end() && (*loc.iter() == '+' || *loc.iter() == '-' + || *loc.iter() == 'Z' || *loc.iter() == 'z')) + { + return err(format_underline("bad offset: should be [+-]HH:MM or Z", + {{source_location(loc), "[+-]HH:MM or Z"}}, + {"pass: +09:00, -05:30", "fail: +9:00, -5:30"})); + } + return ok(value_t::local_datetime); + } + loc.reset(l.iter()); + + if(lex_local_date::invoke(loc)) + { + // bad time may appear after this. + // A space is allowed as a delimiter between local time. But there are + // both cases in which a space becomes valid or invalid. + // - invalid: 2019-06-16 7:00:00 + // - valid : 2019-06-16 07:00:00 + if(loc.iter() != loc.end()) + { + const auto c = *loc.iter(); + if(c == 'T' || c == 't') + { + return err(format_underline("bad time: should be HH:MM:SS.subsec", + {{source_location(loc), "HH:MM:SS.subsec"}}, + {"pass: 1979-05-27T07:32:00, 1979-05-27 07:32:00.999999", + "fail: 1979-05-27T7:32:00, 1979-05-27 17:32"})); + } + if('0' <= c && c <= '9') + { + return err(format_underline("bad time: missing T", + {{source_location(loc), "T or space required here"}}, + {"pass: 1979-05-27T07:32:00, 1979-05-27 07:32:00.999999", + "fail: 1979-05-27T7:32:00, 1979-05-27 7:32"})); + } + if(c == ' ' && std::next(loc.iter()) != loc.end() && + ('0' <= *std::next(loc.iter()) && *std::next(loc.iter())<= '9')) + { + loc.advance(); + return err(format_underline("bad time: should be HH:MM:SS.subsec", + {{source_location(loc), "HH:MM:SS.subsec"}}, + {"pass: 1979-05-27T07:32:00, 1979-05-27 07:32:00.999999", + "fail: 1979-05-27T7:32:00, 1979-05-27 7:32"})); + } + } + return ok(value_t::local_date); + } + loc.reset(l.iter()); + + if(lex_local_time::invoke(loc)) {return ok(value_t::local_time);} + loc.reset(l.iter()); + + if(lex_float::invoke(loc)) + { + if(loc.iter() != loc.end() && *loc.iter() == '_') + { + return err(format_underline("bad float: `_` should be surrounded by digits", + {{source_location(loc), "here"}}, + {"pass: +1.0, -2e-2, 3.141_592_653_589, inf, nan", + "fail: .0, 1., _1.0, 1.0_, 1_.0, 1.0__0"})); + } + return ok(value_t::floating); + } + loc.reset(l.iter()); + + if(lex_integer::invoke(loc)) + { + if(loc.iter() != loc.end()) + { + const auto c = *loc.iter(); + if(c == '_') + { + return err(format_underline("bad integer: `_` should be surrounded by digits", + {{source_location(loc), "here"}}, + {"pass: -42, 1_000, 1_2_3_4_5, 0xC0FFEE, 0b0010, 0o755", + "fail: 1__000, 0123"})); + } + if('0' <= c && c <= '9') + { + // leading zero. point '0' + loc.retrace(); + return err(format_underline("bad integer: leading zero", + {{source_location(loc), "here"}}, + {"pass: -42, 1_000, 1_2_3_4_5, 0xC0FFEE, 0b0010, 0o755", + "fail: 1__000, 0123"})); + } + if(c == ':' || c == '-') + { + return err(format_underline("bad datetime: invalid format", + {{source_location(loc), "here"}}, + {"pass: 1979-05-27T07:32:00-07:00, 1979-05-27 07:32:00.999999Z", + "fail: 1979-05-27T7:32:00-7:00, 1979-05-27 7:32-00:30"})); + } + if(c == '.' || c == 'e' || c == 'E') + { + return err(format_underline("bad float: invalid format", + {{source_location(loc), "here"}}, + {"pass: +1.0, -2e-2, 3.141_592_653_589, inf, nan", + "fail: .0, 1., _1.0, 1.0_, 1_.0, 1.0__0"})); + } + } + return ok(value_t::integer); + } + if(loc.iter() != loc.end() && *loc.iter() == '.') + { + return err(format_underline("bad float: invalid format", + {{source_location(loc), "integer part required before this"}}, + {"pass: +1.0, -2e-2, 3.141_592_653_589, inf, nan", + "fail: .0, 1., _1.0, 1.0_, 1_.0, 1.0__0"})); + } + if(loc.iter() != loc.end() && *loc.iter() == '_') + { + return err(format_underline("bad number: `_` should be surrounded by digits", + {{source_location(loc), "`_` is not surrounded by digits"}}, + {"pass: -42, 1_000, 1_2_3_4_5, 0xC0FFEE, 0b0010, 0o755", + "fail: 1__000, 0123"})); + } + return err(format_underline("bad format: unknown value appeared", + {{source_location(loc), "here"}})); +} + +inline result guess_value_type(const location& loc) +{ + switch(*loc.iter()) + { + case '"' : {return ok(value_t::string); } + case '\'': {return ok(value_t::string); } + case 't' : {return ok(value_t::boolean); } + case 'f' : {return ok(value_t::boolean); } + case '[' : {return ok(value_t::array); } + case '{' : {return ok(value_t::table); } + case 'i' : {return ok(value_t::floating);} // inf. + case 'n' : {return ok(value_t::floating);} // nan. + default : {return guess_number_type(loc);} + } +} + +template +result +parse_value_helper(result, std::string> rslt) +{ + if(rslt.is_ok()) + { + auto comments = rslt.as_ok().second.comments(); + return ok(Value(std::move(rslt.as_ok()), std::move(comments))); + } + else + { + return err(std::move(rslt.as_err())); + } +} + +template +result parse_value(location& loc, const std::size_t n_rec) +{ + const auto first = loc.iter(); + if(first == loc.end()) + { + return err(format_underline("toml::parse_value: input is empty", + {{source_location(loc), ""}})); + } + + const auto type = guess_value_type(loc); + if(!type) + { + return err(type.unwrap_err()); + } + + switch(type.unwrap()) + { + case value_t::boolean : {return parse_value_helper(parse_boolean(loc) );} + case value_t::integer : {return parse_value_helper(parse_integer(loc) );} + case value_t::floating : {return parse_value_helper(parse_floating(loc) );} + case value_t::string : {return parse_value_helper(parse_string(loc) );} + case value_t::offset_datetime: {return parse_value_helper(parse_offset_datetime(loc) );} + case value_t::local_datetime : {return parse_value_helper(parse_local_datetime(loc) );} + case value_t::local_date : {return parse_value_helper(parse_local_date(loc) );} + case value_t::local_time : {return parse_value_helper(parse_local_time(loc) );} + case value_t::array : {return parse_value_helper(parse_array(loc, n_rec));} + case value_t::table : {return parse_value_helper(parse_inline_table(loc, n_rec));} + default: + { + const auto msg = format_underline("toml::parse_value: " + "unknown token appeared", {{source_location(loc), "unknown"}}); + loc.reset(first); + return err(msg); + } + } +} + +inline result, region>, std::string> +parse_table_key(location& loc) +{ + if(auto token = lex_std_table::invoke(loc)) + { + location inner_loc(loc.name(), token.unwrap().str()); + + const auto open = lex_std_table_open::invoke(inner_loc); + if(!open || inner_loc.iter() == inner_loc.end()) + { + throw internal_error(format_underline( + "toml::parse_table_key: no `[`", + {{source_location(inner_loc), "should be `[`"}}), + source_location(inner_loc)); + } + // to skip [ a . b . c ] + // ^----------- this whitespace + lex_ws::invoke(inner_loc); + const auto keys = parse_key(inner_loc); + if(!keys) + { + throw internal_error(format_underline( + "toml::parse_table_key: invalid key", + {{source_location(inner_loc), "not key"}}), + source_location(inner_loc)); + } + // to skip [ a . b . c ] + // ^-- this whitespace + lex_ws::invoke(inner_loc); + const auto close = lex_std_table_close::invoke(inner_loc); + if(!close) + { + throw internal_error(format_underline( + "toml::parse_table_key: no `]`", + {{source_location(inner_loc), "should be `]`"}}), + source_location(inner_loc)); + } + + // after [table.key], newline or EOF(empty table) required. + if(loc.iter() != loc.end()) + { + using lex_newline_after_table_key = + sequence, maybe, lex_newline>; + const auto nl = lex_newline_after_table_key::invoke(loc); + if(!nl) + { + throw syntax_error(format_underline( + "toml::parse_table_key: newline required after [table.key]", + {{source_location(loc), "expected newline"}}), + source_location(loc)); + } + } + return ok(std::make_pair(keys.unwrap().first, token.unwrap())); + } + else + { + return err(format_underline("toml::parse_table_key: " + "not a valid table key", {{source_location(loc), "here"}})); + } +} + +inline result, region>, std::string> +parse_array_table_key(location& loc) +{ + if(auto token = lex_array_table::invoke(loc)) + { + location inner_loc(loc.name(), token.unwrap().str()); + + const auto open = lex_array_table_open::invoke(inner_loc); + if(!open || inner_loc.iter() == inner_loc.end()) + { + throw internal_error(format_underline( + "toml::parse_array_table_key: no `[[`", + {{source_location(inner_loc), "should be `[[`"}}), + source_location(inner_loc)); + } + lex_ws::invoke(inner_loc); + const auto keys = parse_key(inner_loc); + if(!keys) + { + throw internal_error(format_underline( + "toml::parse_array_table_key: invalid key", + {{source_location(inner_loc), "not a key"}}), + source_location(inner_loc)); + } + lex_ws::invoke(inner_loc); + const auto close = lex_array_table_close::invoke(inner_loc); + if(!close) + { + throw internal_error(format_underline( + "toml::parse_array_table_key: no `]]`", + {{source_location(inner_loc), "should be `]]`"}}), + source_location(inner_loc)); + } + + // after [[table.key]], newline or EOF(empty table) required. + if(loc.iter() != loc.end()) + { + using lex_newline_after_table_key = + sequence, maybe, lex_newline>; + const auto nl = lex_newline_after_table_key::invoke(loc); + if(!nl) + { + throw syntax_error(format_underline("toml::" + "parse_array_table_key: newline required after [[table.key]]", + {{source_location(loc), "expected newline"}}), + source_location(loc)); + } + } + return ok(std::make_pair(keys.unwrap().first, token.unwrap())); + } + else + { + return err(format_underline("toml::parse_array_table_key: " + "not a valid table key", {{source_location(loc), "here"}})); + } +} + +// parse table body (key-value pairs until the iter hits the next [tablekey]) +template +result +parse_ml_table(location& loc) +{ + using value_type = Value; + using table_type = typename value_type::table_type; + + const auto first = loc.iter(); + if(first == loc.end()) + { + return ok(table_type{}); + } + + // XXX at lest one newline is needed. + using skip_line = repeat< + sequence, maybe, lex_newline>, at_least<1>>; + skip_line::invoke(loc); + lex_ws::invoke(loc); + + table_type tab; + while(loc.iter() != loc.end()) + { + lex_ws::invoke(loc); + const auto before = loc.iter(); + if(const auto tmp = parse_array_table_key(loc)) // next table found + { + loc.reset(before); + return ok(tab); + } + if(const auto tmp = parse_table_key(loc)) // next table found + { + loc.reset(before); + return ok(tab); + } + + if(const auto kv = parse_key_value_pair(loc, 0)) + { + const auto& kvpair = kv.unwrap(); + const std::vector& keys = kvpair.first.first; + const auto& key_reg = kvpair.first.second; + const value_type& val = kvpair.second; + const auto inserted = + insert_nested_key(tab, val, keys.begin(), keys.end(), key_reg); + if(!inserted) + { + return err(inserted.unwrap_err()); + } + } + else + { + return err(kv.unwrap_err()); + } + + // comment lines are skipped by the above function call. + // However, since the `skip_line` requires at least 1 newline, it fails + // if the file ends with ws and/or comment without newline. + // `skip_line` matches `ws? + comment? + newline`, not `ws` or `comment` + // itself. To skip the last ws and/or comment, call lexers. + // It does not matter if these fails, so the return value is discarded. + lex_ws::invoke(loc); + lex_comment::invoke(loc); + + // skip_line is (whitespace? comment? newline)_{1,}. multiple empty lines + // and comments after the last key-value pairs are allowed. + const auto newline = skip_line::invoke(loc); + if(!newline && loc.iter() != loc.end()) + { + const auto before2 = loc.iter(); + lex_ws::invoke(loc); // skip whitespace + const auto msg = format_underline("toml::parse_table: " + "invalid line format", {{source_location(loc), concat_to_string( + "expected newline, but got '", show_char(*loc.iter()), "'.")}}); + loc.reset(before2); + return err(msg); + } + + // the skip_lines only matches with lines that includes newline. + // to skip the last line that includes comment and/or whitespace + // but no newline, call them one more time. + lex_ws::invoke(loc); + lex_comment::invoke(loc); + } + return ok(tab); +} + +template +result parse_toml_file(location& loc) +{ + using value_type = Value; + using table_type = typename value_type::table_type; + + const auto first = loc.iter(); + if(first == loc.end()) + { + // For empty files, return an empty table with an empty region (zero-length). + // Without the region, error messages would miss the filename. + return ok(value_type(table_type{}, region(loc, first, first), {})); + } + + // put the first line as a region of a file + // Here first != loc.end(), so taking std::next is okay + const region file(loc, first, std::next(loc.iter())); + + // The first successive comments that are separated from the first value + // by an empty line are for a file itself. + // ```toml + // # this is a comment for a file. + // + // key = "the first value" + // ``` + // ```toml + // # this is a comment for "the first value". + // key = "the first value" + // ``` + std::vector comments; + using lex_first_comments = sequence< + repeat, lex_comment, lex_newline>, at_least<1>>, + sequence, lex_newline> + >; + if(const auto token = lex_first_comments::invoke(loc)) + { + location inner_loc(loc.name(), token.unwrap().str()); + while(inner_loc.iter() != inner_loc.end()) + { + maybe::invoke(inner_loc); // remove ws if exists + if(lex_newline::invoke(inner_loc)) + { + assert(inner_loc.iter() == inner_loc.end()); + break; // empty line found. + } + auto com = lex_comment::invoke(inner_loc).unwrap().str(); + com.erase(com.begin()); // remove # sign + comments.push_back(std::move(com)); + lex_newline::invoke(inner_loc); + } + } + + table_type data; + // root object is also a table, but without [tablename] + if(const auto tab = parse_ml_table(loc)) + { + data = std::move(tab.unwrap()); + } + else // failed (empty table is regarded as success in parse_ml_table) + { + return err(tab.unwrap_err()); + } + while(loc.iter() != loc.end()) + { + // here, the region of [table] is regarded as the table-key because + // the table body is normally too big and it is not so informative + // if the first key-value pair of the table is shown in the error + // message. + if(const auto tabkey = parse_array_table_key(loc)) + { + const auto tab = parse_ml_table(loc); + if(!tab){return err(tab.unwrap_err());} + + const auto& tk = tabkey.unwrap(); + const auto& keys = tk.first; + const auto& reg = tk.second; + + const auto inserted = insert_nested_key(data, + value_type(tab.unwrap(), reg, reg.comments()), + keys.begin(), keys.end(), reg, + /*is_array_of_table=*/ true); + if(!inserted) {return err(inserted.unwrap_err());} + + continue; + } + if(const auto tabkey = parse_table_key(loc)) + { + const auto tab = parse_ml_table(loc); + if(!tab){return err(tab.unwrap_err());} + + const auto& tk = tabkey.unwrap(); + const auto& keys = tk.first; + const auto& reg = tk.second; + + const auto inserted = insert_nested_key(data, + value_type(tab.unwrap(), reg, reg.comments()), + keys.begin(), keys.end(), reg); + if(!inserted) {return err(inserted.unwrap_err());} + + continue; + } + return err(format_underline("toml::parse_toml_file: " + "unknown line appeared", {{source_location(loc), "unknown format"}})); + } + + return ok(Value(std::move(data), file, comments)); +} + +template class Table = std::unordered_map, + template class Array = std::vector> +basic_value +parse(std::vector& letters, const std::string& fname) +{ + using value_type = basic_value; + + // append LF. + // Although TOML does not require LF at the EOF, to make parsing logic + // simpler, we "normalize" the content by adding LF if it does not exist. + // It also checks if the last char is CR, to avoid changing the meaning. + // This is not the *best* way to deal with the last character, but is a + // simple and quick fix. + if(!letters.empty() && letters.back() != '\n' && letters.back() != '\r') + { + letters.push_back('\n'); + } + + detail::location loc(std::move(fname), std::move(letters)); + + // skip BOM if exists. + // XXX component of BOM (like 0xEF) exceeds the representable range of + // signed char, so on some (actually, most) of the environment, these cannot + // be compared to char. However, since we are always out of luck, we need to + // check our chars are equivalent to BOM. To do this, first we need to + // convert char to unsigned char to guarantee the comparability. + if(loc.source()->size() >= 3) + { + std::array BOM; + std::memcpy(BOM.data(), loc.source()->data(), 3); + if(BOM[0] == 0xEF && BOM[1] == 0xBB && BOM[2] == 0xBF) + { + loc.advance(3); // BOM found. skip. + } + } + + if (auto data = detail::parse_toml_file(loc)) + { + return std::move(data).unwrap(); + } + else + { + throw syntax_error(std::move(data).unwrap_err(), source_location(loc)); + } +} + +} // detail + +template class Table = std::unordered_map, + template class Array = std::vector> +basic_value +parse(FILE * file, const std::string& fname) +{ + const long beg = std::ftell(file); + if (beg == -1l) + { + throw file_io_error(errno, "Failed to access", fname); + } + + const int res_seekend = std::fseek(file, 0, SEEK_END); + if (res_seekend != 0) + { + throw file_io_error(errno, "Failed to seek", fname); + } + + const long end = std::ftell(file); + if (end == -1l) + { + throw file_io_error(errno, "Failed to access", fname); + } + + const auto fsize = end - beg; + + const auto res_seekbeg = std::fseek(file, beg, SEEK_SET); + if (res_seekbeg != 0) + { + throw file_io_error(errno, "Failed to seek", fname); + } + + // read whole file as a sequence of char + assert(fsize >= 0); + std::vector letters(static_cast(fsize)); + std::fread(letters.data(), sizeof(char), static_cast(fsize), file); + + return detail::parse(letters, fname); +} + +template class Table = std::unordered_map, + template class Array = std::vector> +basic_value +parse(std::istream& is, std::string fname = "unknown file") +{ + const auto beg = is.tellg(); + is.seekg(0, std::ios::end); + const auto end = is.tellg(); + const auto fsize = end - beg; + is.seekg(beg); + + // read whole file as a sequence of char + assert(fsize >= 0); + std::vector letters(static_cast(fsize)); + is.read(letters.data(), fsize); + + return detail::parse(letters, fname); +} + +template class Table = std::unordered_map, + template class Array = std::vector> +basic_value parse(std::string fname) +{ + std::ifstream ifs(fname, std::ios_base::binary); + if(!ifs.good()) + { + throw std::ios_base::failure( + "toml::parse: Error opening file \"" + fname + "\""); + } + ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit); + return parse(ifs, std::move(fname)); +} + +#ifdef TOML11_HAS_STD_FILESYSTEM +// This function just forwards `parse("filename.toml")` to std::string version +// to avoid the ambiguity in overload resolution. +// +// Both std::string and std::filesystem::path are convertible from const char*. +// Without this, both parse(std::string) and parse(std::filesystem::path) +// matches to parse("filename.toml"). This breaks the existing code. +// +// This function exactly matches to the invocation with c-string. +// So this function is preferred than others and the ambiguity disappears. +template class Table = std::unordered_map, + template class Array = std::vector> +basic_value parse(const char* fname) +{ + return parse(std::string(fname)); +} + +template class Table = std::unordered_map, + template class Array = std::vector> +basic_value parse(const std::filesystem::path& fpath) +{ + std::ifstream ifs(fpath, std::ios_base::binary); + if(!ifs.good()) + { + throw std::ios_base::failure( + "toml::parse: Error opening file \"" + fpath.string() + "\""); + } + ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit); + return parse(ifs, fpath.string()); +} +#endif // TOML11_HAS_STD_FILESYSTEM + +} // toml +#endif// TOML11_PARSER_HPP diff --git a/external/toml11/toml/region.hpp b/external/toml11/toml/region.hpp new file mode 100644 index 0000000..72a6f11 --- /dev/null +++ b/external/toml11/toml/region.hpp @@ -0,0 +1,416 @@ +// Copyright Toru Niina 2017. +// Distributed under the MIT License. +#ifndef TOML11_REGION_HPP +#define TOML11_REGION_HPP +#include +#include +#include +#include +#include +#include +#include +#include "color.hpp" + +namespace toml +{ +namespace detail +{ + +// helper function to avoid std::string(0, 'c') or std::string(iter, iter) +template +std::string make_string(Iterator first, Iterator last) +{ + if(first == last) {return "";} + return std::string(first, last); +} +inline std::string make_string(std::size_t len, char c) +{ + if(len == 0) {return "";} + return std::string(len, c); +} + +// region_base is a base class of location and region that are defined below. +// it will be used to generate better error messages. +struct region_base +{ + region_base() = default; + virtual ~region_base() = default; + region_base(const region_base&) = default; + region_base(region_base&& ) = default; + region_base& operator=(const region_base&) = default; + region_base& operator=(region_base&& ) = default; + + virtual bool is_ok() const noexcept {return false;} + virtual char front() const noexcept {return '\0';} + + virtual std::string str() const {return std::string("unknown region");} + virtual std::string name() const {return std::string("unknown file");} + virtual std::string line() const {return std::string("unknown line");} + virtual std::string line_num() const {return std::string("?");} + + // length of the region + virtual std::size_t size() const noexcept {return 0;} + // number of characters in the line before the region + virtual std::size_t before() const noexcept {return 0;} + // number of characters in the line after the region + virtual std::size_t after() const noexcept {return 0;} + + virtual std::vector comments() const {return {};} + // ```toml + // # comment_before + // key = "value" # comment_inline + // ``` +}; + +// location represents a position in a container, which contains a file content. +// it can be considered as a region that contains only one character. +// +// it contains pointer to the file content and iterator that points the current +// location. +struct location final : public region_base +{ + using const_iterator = typename std::vector::const_iterator; + using difference_type = typename std::iterator_traits::difference_type; + using source_ptr = std::shared_ptr>; + + location(std::string source_name, std::vector cont) + : source_(std::make_shared>(std::move(cont))), + line_number_(1), source_name_(std::move(source_name)), iter_(source_->cbegin()) + {} + location(std::string source_name, const std::string& cont) + : source_(std::make_shared>(cont.begin(), cont.end())), + line_number_(1), source_name_(std::move(source_name)), iter_(source_->cbegin()) + {} + + location(const location&) = default; + location(location&&) = default; + location& operator=(const location&) = default; + location& operator=(location&&) = default; + ~location() = default; + + bool is_ok() const noexcept override {return static_cast(source_);} + char front() const noexcept override {return *iter_;} + + // this const prohibits codes like `++(loc.iter())`. + std::add_const::type iter() const noexcept {return iter_;} + + const_iterator begin() const noexcept {return source_->cbegin();} + const_iterator end() const noexcept {return source_->cend();} + + // XXX `location::line_num()` used to be implemented using `std::count` to + // count a number of '\n'. But with a long toml file (typically, 10k lines), + // it becomes intolerably slow because each time it generates error messages, + // it counts '\n' from thousands of characters. To workaround it, I decided + // to introduce `location::line_number_` member variable and synchronize it + // to the location changes the point to look. So an overload of `iter()` + // which returns mutable reference is removed and `advance()`, `retrace()` + // and `reset()` is added. + void advance(difference_type n = 1) noexcept + { + this->line_number_ += static_cast( + std::count(this->iter_, std::next(this->iter_, n), '\n')); + this->iter_ += n; + return; + } + void retrace(difference_type n = 1) noexcept + { + this->line_number_ -= static_cast( + std::count(std::prev(this->iter_, n), this->iter_, '\n')); + this->iter_ -= n; + return; + } + void reset(const_iterator rollback) noexcept + { + // since c++11, std::distance works in both ways for random-access + // iterators and returns a negative value if `first > last`. + if(0 <= std::distance(rollback, this->iter_)) // rollback < iter + { + this->line_number_ -= static_cast( + std::count(rollback, this->iter_, '\n')); + } + else // iter < rollback [[unlikely]] + { + this->line_number_ += static_cast( + std::count(this->iter_, rollback, '\n')); + } + this->iter_ = rollback; + return; + } + + std::string str() const override {return make_string(1, *this->iter());} + std::string name() const override {return source_name_;} + + std::string line_num() const override + { + return std::to_string(this->line_number_); + } + + std::string line() const override + { + return make_string(this->line_begin(), this->line_end()); + } + + const_iterator line_begin() const noexcept + { + using reverse_iterator = std::reverse_iterator; + return std::find(reverse_iterator(this->iter()), + reverse_iterator(this->begin()), '\n').base(); + } + const_iterator line_end() const noexcept + { + return std::find(this->iter(), this->end(), '\n'); + } + + // location is always points a character. so the size is 1. + std::size_t size() const noexcept override + { + return 1u; + } + std::size_t before() const noexcept override + { + const auto sz = std::distance(this->line_begin(), this->iter()); + assert(sz >= 0); + return static_cast(sz); + } + std::size_t after() const noexcept override + { + const auto sz = std::distance(this->iter(), this->line_end()); + assert(sz >= 0); + return static_cast(sz); + } + + source_ptr const& source() const& noexcept {return source_;} + source_ptr&& source() && noexcept {return std::move(source_);} + + private: + + source_ptr source_; + std::size_t line_number_; + std::string source_name_; + const_iterator iter_; +}; + +// region represents a range in a container, which contains a file content. +// +// it contains pointer to the file content and iterator that points the first +// and last location. +struct region final : public region_base +{ + using const_iterator = typename std::vector::const_iterator; + using source_ptr = std::shared_ptr>; + + // delete default constructor. source_ never be null. + region() = delete; + + explicit region(const location& loc) + : source_(loc.source()), source_name_(loc.name()), + first_(loc.iter()), last_(loc.iter()) + {} + explicit region(location&& loc) + : source_(loc.source()), source_name_(loc.name()), + first_(loc.iter()), last_(loc.iter()) + {} + + region(const location& loc, const_iterator f, const_iterator l) + : source_(loc.source()), source_name_(loc.name()), first_(f), last_(l) + {} + region(location&& loc, const_iterator f, const_iterator l) + : source_(loc.source()), source_name_(loc.name()), first_(f), last_(l) + {} + + region(const region&) = default; + region(region&&) = default; + region& operator=(const region&) = default; + region& operator=(region&&) = default; + ~region() = default; + + region& operator+=(const region& other) + { + // different regions cannot be concatenated + assert(this->source_ == other.source_ && this->last_ == other.first_); + + this->last_ = other.last_; + return *this; + } + + bool is_ok() const noexcept override {return static_cast(source_);} + char front() const noexcept override {return *first_;} + + std::string str() const override {return make_string(first_, last_);} + std::string line() const override + { + if(this->contain_newline()) + { + return make_string(this->line_begin(), + std::find(this->line_begin(), this->last(), '\n')); + } + return make_string(this->line_begin(), this->line_end()); + } + std::string line_num() const override + { + return std::to_string(1 + std::count(this->begin(), this->first(), '\n')); + } + + std::size_t size() const noexcept override + { + const auto sz = std::distance(first_, last_); + assert(sz >= 0); + return static_cast(sz); + } + std::size_t before() const noexcept override + { + const auto sz = std::distance(this->line_begin(), this->first()); + assert(sz >= 0); + return static_cast(sz); + } + std::size_t after() const noexcept override + { + const auto sz = std::distance(this->last(), this->line_end()); + assert(sz >= 0); + return static_cast(sz); + } + + bool contain_newline() const noexcept + { + return std::find(this->first(), this->last(), '\n') != this->last(); + } + + const_iterator line_begin() const noexcept + { + using reverse_iterator = std::reverse_iterator; + return std::find(reverse_iterator(this->first()), + reverse_iterator(this->begin()), '\n').base(); + } + const_iterator line_end() const noexcept + { + return std::find(this->last(), this->end(), '\n'); + } + + const_iterator begin() const noexcept {return source_->cbegin();} + const_iterator end() const noexcept {return source_->cend();} + const_iterator first() const noexcept {return first_;} + const_iterator last() const noexcept {return last_;} + + source_ptr const& source() const& noexcept {return source_;} + source_ptr&& source() && noexcept {return std::move(source_);} + + std::string name() const override {return source_name_;} + + std::vector comments() const override + { + // assuming the current region (`*this`) points a value. + // ```toml + // a = "value" + // ^^^^^^^- this region + // ``` + using rev_iter = std::reverse_iterator; + + std::vector com{}; + { + // find comments just before the current region. + // ```toml + // # this should be collected. + // # this also. + // a = value # not this. + // ``` + + // # this is a comment for `a`, not array elements. + // a = [1, 2, 3, 4, 5] + if(this->first() == std::find_if(this->line_begin(), this->first(), + [](const char c) noexcept -> bool {return c == '[' || c == '{';})) + { + auto iter = this->line_begin(); // points the first character + while(iter != this->begin()) + { + iter = std::prev(iter); + + // range [line_start, iter) represents the previous line + const auto line_start = std::find( + rev_iter(iter), rev_iter(this->begin()), '\n').base(); + const auto comment_found = std::find(line_start, iter, '#'); + if(comment_found == iter) + { + break; // comment not found. + } + + // exclude the following case. + // > a = "foo" # comment // <-- this is not a comment for b but a. + // > b = "current value" + if(std::all_of(line_start, comment_found, + [](const char c) noexcept -> bool { + return c == ' ' || c == '\t'; + })) + { + // unwrap the first '#' by std::next. + auto s = make_string(std::next(comment_found), iter); + if(!s.empty() && s.back() == '\r') {s.pop_back();} + com.push_back(std::move(s)); + } + else + { + break; + } + iter = line_start; + } + } + } + + if(com.size() > 1) + { + std::reverse(com.begin(), com.end()); + } + + { + // find comments just after the current region. + // ```toml + // # not this. + // a = value # this one. + // a = [ # not this (technically difficult) + // + // ] # and this. + // ``` + // The reason why it's difficult is that it requires parsing in the + // following case. + // ```toml + // a = [ 10 # this comment is for `10`. not for `a` but `a[0]`. + // # ... + // ] # this is apparently a comment for a. + // + // b = [ + // 3.14 ] # there is no way to add a comment to `3.14` currently. + // + // c = [ + // 3.14 # do this if you need a comment here. + // ] + // ``` + const auto comment_found = + std::find(this->last(), this->line_end(), '#'); + if(comment_found != this->line_end()) // '#' found + { + // table = {key = "value"} # what is this for? + // the above comment is not for "value", but {key="value"}. + if(comment_found == std::find_if(this->last(), comment_found, + [](const char c) noexcept -> bool { + return !(c == ' ' || c == '\t' || c == ','); + })) + { + // unwrap the first '#' by std::next. + auto s = make_string(std::next(comment_found), this->line_end()); + if(!s.empty() && s.back() == '\r') {s.pop_back();} + com.push_back(std::move(s)); + } + } + } + return com; + } + + private: + + source_ptr source_; + std::string source_name_; + const_iterator first_, last_; +}; + +} // detail +} // toml +#endif// TOML11_REGION_H diff --git a/external/toml11/toml/result.hpp b/external/toml11/toml/result.hpp new file mode 100644 index 0000000..77cd46c --- /dev/null +++ b/external/toml11/toml/result.hpp @@ -0,0 +1,717 @@ +// Copyright Toru Niina 2017. +// Distributed under the MIT License. +#ifndef TOML11_RESULT_HPP +#define TOML11_RESULT_HPP +#include "traits.hpp" +#include +#include +#include +#include +#include +#include +#include + +namespace toml +{ + +template +struct success +{ + using value_type = T; + value_type value; + + explicit success(const value_type& v) + noexcept(std::is_nothrow_copy_constructible::value) + : value(v) + {} + explicit success(value_type&& v) + noexcept(std::is_nothrow_move_constructible::value) + : value(std::move(v)) + {} + + template + explicit success(U&& v): value(std::forward(v)) {} + + template + explicit success(const success& v): value(v.value) {} + template + explicit success(success&& v): value(std::move(v.value)) {} + + ~success() = default; + success(const success&) = default; + success(success&&) = default; + success& operator=(const success&) = default; + success& operator=(success&&) = default; +}; + +template +struct failure +{ + using value_type = T; + value_type value; + + explicit failure(const value_type& v) + noexcept(std::is_nothrow_copy_constructible::value) + : value(v) + {} + explicit failure(value_type&& v) + noexcept(std::is_nothrow_move_constructible::value) + : value(std::move(v)) + {} + + template + explicit failure(U&& v): value(std::forward(v)) {} + + template + explicit failure(const failure& v): value(v.value) {} + template + explicit failure(failure&& v): value(std::move(v.value)) {} + + ~failure() = default; + failure(const failure&) = default; + failure(failure&&) = default; + failure& operator=(const failure&) = default; + failure& operator=(failure&&) = default; +}; + +template +success::type>::type> +ok(T&& v) +{ + return success< + typename std::remove_cv::type>::type + >(std::forward(v)); +} +template +failure::type>::type> +err(T&& v) +{ + return failure< + typename std::remove_cv::type>::type + >(std::forward(v)); +} + +inline success ok(const char* literal) +{ + return success(std::string(literal)); +} +inline failure err(const char* literal) +{ + return failure(std::string(literal)); +} + + +template +struct result +{ + using value_type = T; + using error_type = E; + using success_type = success; + using failure_type = failure; + + result(const success_type& s): is_ok_(true) + { + auto tmp = ::new(std::addressof(this->succ)) success_type(s); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + } + result(const failure_type& f): is_ok_(false) + { + auto tmp = ::new(std::addressof(this->fail)) failure_type(f); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + } + result(success_type&& s): is_ok_(true) + { + auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s)); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + } + result(failure_type&& f): is_ok_(false) + { + auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f)); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + } + + template + result(const success& s): is_ok_(true) + { + auto tmp = ::new(std::addressof(this->succ)) success_type(s.value); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + } + template + result(const failure& f): is_ok_(false) + { + auto tmp = ::new(std::addressof(this->fail)) failure_type(f.value); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + } + template + result(success&& s): is_ok_(true) + { + auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s.value)); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + } + template + result(failure&& f): is_ok_(false) + { + auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f.value)); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + } + + result& operator=(const success_type& s) + { + this->cleanup(); + this->is_ok_ = true; + auto tmp = ::new(std::addressof(this->succ)) success_type(s); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + return *this; + } + result& operator=(const failure_type& f) + { + this->cleanup(); + this->is_ok_ = false; + auto tmp = ::new(std::addressof(this->fail)) failure_type(f); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + return *this; + } + result& operator=(success_type&& s) + { + this->cleanup(); + this->is_ok_ = true; + auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s)); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + return *this; + } + result& operator=(failure_type&& f) + { + this->cleanup(); + this->is_ok_ = false; + auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f)); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + return *this; + } + + template + result& operator=(const success& s) + { + this->cleanup(); + this->is_ok_ = true; + auto tmp = ::new(std::addressof(this->succ)) success_type(s.value); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + return *this; + } + template + result& operator=(const failure& f) + { + this->cleanup(); + this->is_ok_ = false; + auto tmp = ::new(std::addressof(this->fail)) failure_type(f.value); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + return *this; + } + template + result& operator=(success&& s) + { + this->cleanup(); + this->is_ok_ = true; + auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s.value)); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + return *this; + } + template + result& operator=(failure&& f) + { + this->cleanup(); + this->is_ok_ = false; + auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f.value)); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + return *this; + } + + ~result() noexcept {this->cleanup();} + + result(const result& other): is_ok_(other.is_ok()) + { + if(other.is_ok()) + { + auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok()); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + } + else + { + auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err()); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + } + } + result(result&& other): is_ok_(other.is_ok()) + { + if(other.is_ok()) + { + auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok())); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + } + else + { + auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err())); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + } + } + + template + result(const result& other): is_ok_(other.is_ok()) + { + if(other.is_ok()) + { + auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok()); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + } + else + { + auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err()); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + } + } + template + result(result&& other): is_ok_(other.is_ok()) + { + if(other.is_ok()) + { + auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok())); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + } + else + { + auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err())); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + } + } + + result& operator=(const result& other) + { + this->cleanup(); + if(other.is_ok()) + { + auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok()); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + } + else + { + auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err()); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + } + is_ok_ = other.is_ok(); + return *this; + } + result& operator=(result&& other) + { + this->cleanup(); + if(other.is_ok()) + { + auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok())); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + } + else + { + auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err())); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + } + is_ok_ = other.is_ok(); + return *this; + } + + template + result& operator=(const result& other) + { + this->cleanup(); + if(other.is_ok()) + { + auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok()); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + } + else + { + auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err()); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + } + is_ok_ = other.is_ok(); + return *this; + } + template + result& operator=(result&& other) + { + this->cleanup(); + if(other.is_ok()) + { + auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok())); + assert(tmp == std::addressof(this->succ)); + (void)tmp; + } + else + { + auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err())); + assert(tmp == std::addressof(this->fail)); + (void)tmp; + } + is_ok_ = other.is_ok(); + return *this; + } + + bool is_ok() const noexcept {return is_ok_;} + bool is_err() const noexcept {return !is_ok_;} + + operator bool() const noexcept {return is_ok_;} + + value_type& unwrap() & + { + if(is_err()) + { + throw std::runtime_error("toml::result: bad unwrap: " + + format_error(this->as_err())); + } + return this->succ.value; + } + value_type const& unwrap() const& + { + if(is_err()) + { + throw std::runtime_error("toml::result: bad unwrap: " + + format_error(this->as_err())); + } + return this->succ.value; + } + value_type&& unwrap() && + { + if(is_err()) + { + throw std::runtime_error("toml::result: bad unwrap: " + + format_error(this->as_err())); + } + return std::move(this->succ.value); + } + + value_type& unwrap_or(value_type& opt) & + { + if(is_err()) {return opt;} + return this->succ.value; + } + value_type const& unwrap_or(value_type const& opt) const& + { + if(is_err()) {return opt;} + return this->succ.value; + } + value_type unwrap_or(value_type opt) && + { + if(is_err()) {return opt;} + return this->succ.value; + } + + error_type& unwrap_err() & + { + if(is_ok()) {throw std::runtime_error("toml::result: bad unwrap_err");} + return this->fail.value; + } + error_type const& unwrap_err() const& + { + if(is_ok()) {throw std::runtime_error("toml::result: bad unwrap_err");} + return this->fail.value; + } + error_type&& unwrap_err() && + { + if(is_ok()) {throw std::runtime_error("toml::result: bad unwrap_err");} + return std::move(this->fail.value); + } + + value_type& as_ok() & noexcept {return this->succ.value;} + value_type const& as_ok() const& noexcept {return this->succ.value;} + value_type&& as_ok() && noexcept {return std::move(this->succ.value);} + + error_type& as_err() & noexcept {return this->fail.value;} + error_type const& as_err() const& noexcept {return this->fail.value;} + error_type&& as_err() && noexcept {return std::move(this->fail.value);} + + + // prerequisities + // F: T -> U + // retval: result + template + result, error_type> + map(F&& f) & + { + if(this->is_ok()){return ok(f(this->as_ok()));} + return err(this->as_err()); + } + template + result, error_type> + map(F&& f) const& + { + if(this->is_ok()){return ok(f(this->as_ok()));} + return err(this->as_err()); + } + template + result, error_type> + map(F&& f) && + { + if(this->is_ok()){return ok(f(std::move(this->as_ok())));} + return err(std::move(this->as_err())); + } + + // prerequisities + // F: E -> F + // retval: result + template + result> + map_err(F&& f) & + { + if(this->is_err()){return err(f(this->as_err()));} + return ok(this->as_ok()); + } + template + result> + map_err(F&& f) const& + { + if(this->is_err()){return err(f(this->as_err()));} + return ok(this->as_ok()); + } + template + result> + map_err(F&& f) && + { + if(this->is_err()){return err(f(std::move(this->as_err())));} + return ok(std::move(this->as_ok())); + } + + // prerequisities + // F: T -> U + // retval: U + template + detail::return_type_of_t + map_or_else(F&& f, U&& opt) & + { + if(this->is_err()){return std::forward(opt);} + return f(this->as_ok()); + } + template + detail::return_type_of_t + map_or_else(F&& f, U&& opt) const& + { + if(this->is_err()){return std::forward(opt);} + return f(this->as_ok()); + } + template + detail::return_type_of_t + map_or_else(F&& f, U&& opt) && + { + if(this->is_err()){return std::forward(opt);} + return f(std::move(this->as_ok())); + } + + // prerequisities + // F: E -> U + // retval: U + template + detail::return_type_of_t + map_err_or_else(F&& f, U&& opt) & + { + if(this->is_ok()){return std::forward(opt);} + return f(this->as_err()); + } + template + detail::return_type_of_t + map_err_or_else(F&& f, U&& opt) const& + { + if(this->is_ok()){return std::forward(opt);} + return f(this->as_err()); + } + template + detail::return_type_of_t + map_err_or_else(F&& f, U&& opt) && + { + if(this->is_ok()){return std::forward(opt);} + return f(std::move(this->as_err())); + } + + // prerequisities: + // F: func T -> U + // toml::err(error_type) should be convertible to U. + // normally, type U is another result and E is convertible to F + template + detail::return_type_of_t + and_then(F&& f) & + { + if(this->is_ok()){return f(this->as_ok());} + return err(this->as_err()); + } + template + detail::return_type_of_t + and_then(F&& f) const& + { + if(this->is_ok()){return f(this->as_ok());} + return err(this->as_err()); + } + template + detail::return_type_of_t + and_then(F&& f) && + { + if(this->is_ok()){return f(std::move(this->as_ok()));} + return err(std::move(this->as_err())); + } + + // prerequisities: + // F: func E -> U + // toml::ok(value_type) should be convertible to U. + // normally, type U is another result and T is convertible to S + template + detail::return_type_of_t + or_else(F&& f) & + { + if(this->is_err()){return f(this->as_err());} + return ok(this->as_ok()); + } + template + detail::return_type_of_t + or_else(F&& f) const& + { + if(this->is_err()){return f(this->as_err());} + return ok(this->as_ok()); + } + template + detail::return_type_of_t + or_else(F&& f) && + { + if(this->is_err()){return f(std::move(this->as_err()));} + return ok(std::move(this->as_ok())); + } + + // if *this is error, returns *this. otherwise, returns other. + result and_other(const result& other) const& + { + return this->is_err() ? *this : other; + } + result and_other(result&& other) && + { + return this->is_err() ? std::move(*this) : std::move(other); + } + + // if *this is okay, returns *this. otherwise, returns other. + result or_other(const result& other) const& + { + return this->is_ok() ? *this : other; + } + result or_other(result&& other) && + { + return this->is_ok() ? std::move(*this) : std::move(other); + } + + void swap(result& other) + { + result tmp(std::move(*this)); + *this = std::move(other); + other = std::move(tmp); + return ; + } + + private: + + static std::string format_error(std::exception const& excpt) + { + return std::string(excpt.what()); + } + template::value, std::nullptr_t>::type = nullptr> + static std::string format_error(U const& others) + { + std::ostringstream oss; oss << others; + return oss.str(); + } + + void cleanup() noexcept + { + if(this->is_ok_) {this->succ.~success_type();} + else {this->fail.~failure_type();} + return; + } + + private: + + bool is_ok_; + union + { + success_type succ; + failure_type fail; + }; +}; + +template +void swap(result& lhs, result& rhs) +{ + lhs.swap(rhs); + return; +} + +// this might be confusing because it eagerly evaluated, while in the other +// cases operator && and || are short-circuited. +// +// template +// inline result +// operator&&(const result& lhs, const result& rhs) noexcept +// { +// return lhs.is_ok() ? rhs : lhs; +// } +// +// template +// inline result +// operator||(const result& lhs, const result& rhs) noexcept +// { +// return lhs.is_ok() ? lhs : rhs; +// } + +// ---------------------------------------------------------------------------- +// re-use result as a optional with none_t + +namespace detail +{ +struct none_t {}; +inline bool operator==(const none_t&, const none_t&) noexcept {return true;} +inline bool operator!=(const none_t&, const none_t&) noexcept {return false;} +inline bool operator< (const none_t&, const none_t&) noexcept {return false;} +inline bool operator<=(const none_t&, const none_t&) noexcept {return true;} +inline bool operator> (const none_t&, const none_t&) noexcept {return false;} +inline bool operator>=(const none_t&, const none_t&) noexcept {return true;} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const none_t&) +{ + os << "none"; + return os; +} +inline failure none() noexcept {return failure{none_t{}};} +} // detail +} // toml11 +#endif// TOML11_RESULT_H diff --git a/external/toml11/toml/serializer.hpp b/external/toml11/toml/serializer.hpp new file mode 100644 index 0000000..23fb89a --- /dev/null +++ b/external/toml11/toml/serializer.hpp @@ -0,0 +1,994 @@ +// Copyright Toru Niina 2019. +// Distributed under the MIT License. +#ifndef TOML11_SERIALIZER_HPP +#define TOML11_SERIALIZER_HPP +#include +#include + +#include + +#if defined(_WIN32) +#include +#elif defined(__APPLE__) || defined(__FreeBSD__) +#include +#elif defined(__linux__) +#include +#endif + +#include "lexer.hpp" +#include "value.hpp" + +namespace toml +{ + +// This function serialize a key. It checks a string is a bare key and +// escapes special characters if the string is not compatible to a bare key. +// ```cpp +// std::string k("non.bare.key"); // the key itself includes `.`s. +// std::string formatted = toml::format_key(k); +// assert(formatted == "\"non.bare.key\""); +// ``` +// +// This function is exposed to make it easy to write a user-defined serializer. +// Since toml restricts characters available in a bare key, generally a string +// should be escaped. But checking whether a string needs to be surrounded by +// a `"` and escaping some special character is boring. +template +std::basic_string +format_key(const std::basic_string& k) +{ + if(k.empty()) + { + return std::string("\"\""); + } + + // check the key can be a bare (unquoted) key + detail::location loc(k, std::vector(k.begin(), k.end())); + detail::lex_unquoted_key::invoke(loc); + if(loc.iter() == loc.end()) + { + return k; // all the tokens are consumed. the key is unquoted-key. + } + + //if it includes special characters, then format it in a "quoted" key. + std::basic_string serialized("\""); + for(const char c : k) + { + switch(c) + { + case '\\': {serialized += "\\\\"; break;} + case '\"': {serialized += "\\\""; break;} + case '\b': {serialized += "\\b"; break;} + case '\t': {serialized += "\\t"; break;} + case '\f': {serialized += "\\f"; break;} + case '\n': {serialized += "\\n"; break;} + case '\r': {serialized += "\\r"; break;} + default: { + if (c >= 0x00 && c < 0x20) + { + std::array buf; + std::snprintf(buf.data(), buf.size(), "\\u00%02x", static_cast(c)); + serialized += buf.data(); + } + else + { + serialized += c; + } + break; + } + } + } + serialized += "\""; + return serialized; +} + +template +std::basic_string +format_keys(const std::vector>& keys) +{ + if(keys.empty()) + { + return std::string("\"\""); + } + + std::basic_string serialized; + for(const auto& ky : keys) + { + serialized += format_key(ky); + serialized += charT('.'); + } + serialized.pop_back(); // remove the last dot '.' + return serialized; +} + +template +struct serializer +{ + static_assert(detail::is_basic_value::value, + "toml::serializer is for toml::value and its variants, " + "toml::basic_value<...>."); + + using value_type = Value; + using key_type = typename value_type::key_type ; + using comment_type = typename value_type::comment_type ; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; + + serializer(const std::size_t w = 80u, + const int float_prec = std::numeric_limits::max_digits10, + const bool can_be_inlined = false, + const bool no_comment = false, + std::vector ks = {}, + const bool value_has_comment = false) + : can_be_inlined_(can_be_inlined), no_comment_(no_comment), + value_has_comment_(value_has_comment && !no_comment), + float_prec_(float_prec), width_(w), keys_(std::move(ks)) + {} + ~serializer() = default; + + std::string operator()(const boolean_type& b) const + { + return b ? "true" : "false"; + } + std::string operator()(const integer_type i) const + { +#if defined(_WIN32) + _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); + const std::string original_locale(setlocale(LC_NUMERIC, nullptr)); + setlocale(LC_NUMERIC, "C"); +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) + const auto c_locale = newlocale(LC_NUMERIC_MASK, "C", locale_t(0)); + locale_t original_locale(0); + if(c_locale != locale_t(0)) + { + original_locale = uselocale(c_locale); + } +#endif + + const auto str = std::to_string(i); + +#if defined(_WIN32) + setlocale(LC_NUMERIC, original_locale.c_str()); + _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) + if(original_locale != locale_t(0)) + { + uselocale(original_locale); + } +#endif + return str; + } + std::string operator()(const floating_type f) const + { + if(std::isnan(f)) + { + if(std::signbit(f)) + { + return std::string("-nan"); + } + else + { + return std::string("nan"); + } + } + else if(!std::isfinite(f)) + { + if(std::signbit(f)) + { + return std::string("-inf"); + } + else + { + return std::string("inf"); + } + } + + // set locale to "C". + // To make it thread-local, we use OS-specific features. + // If we set process-global locale, it can break other thread that also + // outputs something simultaneously. +#if defined(_WIN32) + _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); + const std::string original_locale(setlocale(LC_NUMERIC, nullptr)); + setlocale(LC_NUMERIC, "C"); +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) + const auto c_locale = newlocale(LC_NUMERIC_MASK, "C", locale_t(0)); + locale_t original_locale(0); + if(c_locale != locale_t(0)) + { + original_locale = uselocale(c_locale); + } +#endif + + const auto fmt = "%.*g"; + const auto bsz = std::snprintf(nullptr, 0, fmt, this->float_prec_, f); + // +1 for null character(\0) + std::vector buf(static_cast(bsz + 1), '\0'); + std::snprintf(buf.data(), buf.size(), fmt, this->float_prec_, f); + + // restore the original locale +#if defined(_WIN32) + setlocale(LC_NUMERIC, original_locale.c_str()); + _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) + if(original_locale != locale_t(0)) + { + uselocale(original_locale); + } +#endif + + std::string token(buf.begin(), std::prev(buf.end())); + if(!token.empty() && token.back() == '.') // 1. => 1.0 + { + token += '0'; + } + + const auto e = std::find_if( + token.cbegin(), token.cend(), [](const char c) noexcept -> bool { + return c == 'e' || c == 'E'; + }); + const auto has_exponent = (token.cend() != e); + const auto has_fraction = (token.cend() != std::find( + token.cbegin(), token.cend(), '.')); + + if(!has_exponent && !has_fraction) + { + // the resulting value does not have any float specific part! + token += ".0"; + } + return token; + } + std::string operator()(const string_type& s) const + { + if(s.kind == string_t::basic) + { + if((std::find(s.str.cbegin(), s.str.cend(), '\n') != s.str.cend() || + std::find(s.str.cbegin(), s.str.cend(), '\"') != s.str.cend()) && + this->width_ != (std::numeric_limits::max)()) + { + // if linefeed or double-quote is contained, + // make it multiline basic string. + const auto escaped = this->escape_ml_basic_string(s.str); + std::string open("\"\"\""); + std::string close("\"\"\""); + if(escaped.find('\n') != std::string::npos || + this->width_ < escaped.size() + 6) + { + // if the string body contains newline or is enough long, + // add newlines after and before delimiters. + open += "\n"; + close = std::string("\\\n") + close; + } + return open + escaped + close; + } + + // no linefeed. try to make it oneline-string. + std::string oneline = this->escape_basic_string(s.str); + if(oneline.size() + 2 < width_ || width_ < 2) + { + const std::string quote("\""); + return quote + oneline + quote; + } + + // the line is too long compared to the specified width. + // split it into multiple lines. + std::string token("\"\"\"\n"); + while(!oneline.empty()) + { + if(oneline.size() < width_) + { + token += oneline; + oneline.clear(); + } + else if(oneline.at(width_-2) == '\\') + { + token += oneline.substr(0, width_-2); + token += "\\\n"; + oneline.erase(0, width_-2); + } + else + { + token += oneline.substr(0, width_-1); + token += "\\\n"; + oneline.erase(0, width_-1); + } + } + return token + std::string("\\\n\"\"\""); + } + else // the string `s` is literal-string. + { + if(std::find(s.str.cbegin(), s.str.cend(), '\n') != s.str.cend() || + std::find(s.str.cbegin(), s.str.cend(), '\'') != s.str.cend() ) + { + std::string open("'''"); + if(this->width_ + 6 < s.str.size()) + { + open += '\n'; // the first newline is ignored by TOML spec + } + const std::string close("'''"); + return open + s.str + close; + } + else + { + const std::string quote("'"); + return quote + s.str + quote; + } + } + } + + std::string operator()(const local_date_type& d) const + { + std::ostringstream oss; + oss << d; + return oss.str(); + } + std::string operator()(const local_time_type& t) const + { + std::ostringstream oss; + oss << t; + return oss.str(); + } + std::string operator()(const local_datetime_type& dt) const + { + std::ostringstream oss; + oss << dt; + return oss.str(); + } + std::string operator()(const offset_datetime_type& odt) const + { + std::ostringstream oss; + oss << odt; + return oss.str(); + } + + std::string operator()(const array_type& v) const + { + if(v.empty()) + { + return std::string("[]"); + } + if(this->is_array_of_tables(v)) + { + return make_array_of_tables(v); + } + + // not an array of tables. normal array. + // first, try to make it inline if none of the elements have a comment. + if( ! this->has_comment_inside(v)) + { + const auto inl = this->make_inline_array(v); + if(inl.size() < this->width_ && + std::find(inl.cbegin(), inl.cend(), '\n') == inl.cend()) + { + return inl; + } + } + + // if the length exceeds this->width_, print multiline array. + // key = [ + // # ... + // 42, + // ... + // ] + std::string token; + std::string current_line; + token += "[\n"; + for(const auto& item : v) + { + if( ! item.comments().empty() && !no_comment_) + { + // if comment exists, the element must be the only element in the line. + // e.g. the following is not allowed. + // ```toml + // array = [ + // # comment for what? + // 1, 2, 3, 4, 5 + // ] + // ``` + if(!current_line.empty()) + { + if(current_line.back() != '\n') + { + current_line += '\n'; + } + token += current_line; + current_line.clear(); + } + for(const auto& c : item.comments()) + { + token += '#'; + token += c; + token += '\n'; + } + token += toml::visit(*this, item); + if(!token.empty() && token.back() == '\n') {token.pop_back();} + token += ",\n"; + continue; + } + std::string next_elem; + if(item.is_table()) + { + serializer ser(*this); + ser.can_be_inlined_ = true; + ser.width_ = (std::numeric_limits::max)(); + next_elem += toml::visit(ser, item); + } + else + { + next_elem += toml::visit(*this, item); + } + + // comma before newline. + if(!next_elem.empty() && next_elem.back() == '\n') {next_elem.pop_back();} + + // if current line does not exceeds the width limit, continue. + if(current_line.size() + next_elem.size() + 1 < this->width_) + { + current_line += next_elem; + current_line += ','; + } + else if(current_line.empty()) + { + // if current line was empty, force put the next_elem because + // next_elem is not splittable + token += next_elem; + token += ",\n"; + // current_line is kept empty + } + else // reset current_line + { + assert(current_line.back() == ','); + token += current_line; + token += '\n'; + current_line = next_elem; + current_line += ','; + } + } + if(!current_line.empty()) + { + if(!current_line.empty() && current_line.back() != '\n') + { + current_line += '\n'; + } + token += current_line; + } + token += "]\n"; + return token; + } + + // templatize for any table-like container + std::string operator()(const table_type& v) const + { + // if an element has a comment, then it can't be inlined. + // table = {# how can we write a comment for this? key = "value"} + if(this->can_be_inlined_ && !(this->has_comment_inside(v))) + { + std::string token; + if(!this->keys_.empty()) + { + token += format_key(this->keys_.back()); + token += " = "; + } + token += this->make_inline_table(v); + if(token.size() < this->width_ && + token.end() == std::find(token.begin(), token.end(), '\n')) + { + return token; + } + } + + std::string token; + if(!keys_.empty()) + { + token += '['; + token += format_keys(keys_); + token += "]\n"; + } + token += this->make_multiline_table(v); + return token; + } + + private: + + std::string escape_basic_string(const std::string& s) const + { + //XXX assuming `s` is a valid utf-8 sequence. + std::string retval; + for(const char c : s) + { + switch(c) + { + case '\\': {retval += "\\\\"; break;} + case '\"': {retval += "\\\""; break;} + case '\b': {retval += "\\b"; break;} + case '\t': {retval += "\\t"; break;} + case '\f': {retval += "\\f"; break;} + case '\n': {retval += "\\n"; break;} + case '\r': {retval += "\\r"; break;} + default : + { + if((0x00 <= c && c <= 0x08) || (0x0A <= c && c <= 0x1F) || c == 0x7F) + { + retval += "\\u00"; + retval += char(48 + (c / 16)); + retval += char((c % 16 < 10 ? 48 : 55) + (c % 16)); + } + else + { + retval += c; + } + } + } + } + return retval; + } + + std::string escape_ml_basic_string(const std::string& s) const + { + std::string retval; + for(auto i=s.cbegin(), e=s.cend(); i!=e; ++i) + { + switch(*i) + { + case '\\': {retval += "\\\\"; break;} + // One or two consecutive "s are allowed. + // Later we will check there are no three consecutive "s. + // case '\"': {retval += "\\\""; break;} + case '\b': {retval += "\\b"; break;} + case '\t': {retval += "\\t"; break;} + case '\f': {retval += "\\f"; break;} + case '\n': {retval += "\n"; break;} + case '\r': + { + if(std::next(i) != e && *std::next(i) == '\n') + { + retval += "\r\n"; + ++i; + } + else + { + retval += "\\r"; + } + break; + } + default : + { + const auto c = *i; + if((0x00 <= c && c <= 0x08) || (0x0A <= c && c <= 0x1F) || c == 0x7F) + { + retval += "\\u00"; + retval += char(48 + (c / 16)); + retval += char((c % 16 < 10 ? 48 : 55) + (c % 16)); + } + else + { + retval += c; + } + } + + } + } + // Only 1 or 2 consecutive `"`s are allowed in multiline basic string. + // 3 consecutive `"`s are considered as a closing delimiter. + // We need to check if there are 3 or more consecutive `"`s and insert + // backslash to break them down into several short `"`s like the `str6` + // in the following example. + // ```toml + // str4 = """Here are two quotation marks: "". Simple enough.""" + // # str5 = """Here are three quotation marks: """.""" # INVALID + // str5 = """Here are three quotation marks: ""\".""" + // str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\".""" + // ``` + auto found_3_quotes = retval.find("\"\"\""); + while(found_3_quotes != std::string::npos) + { + retval.replace(found_3_quotes, 3, "\"\"\\\""); + found_3_quotes = retval.find("\"\"\""); + } + return retval; + } + + // if an element of a table or an array has a comment, it cannot be inlined. + bool has_comment_inside(const array_type& a) const noexcept + { + // if no_comment is set, comments would not be written. + if(this->no_comment_) {return false;} + + for(const auto& v : a) + { + if(!v.comments().empty()) {return true;} + } + return false; + } + bool has_comment_inside(const table_type& t) const noexcept + { + // if no_comment is set, comments would not be written. + if(this->no_comment_) {return false;} + + for(const auto& kv : t) + { + if(!kv.second.comments().empty()) {return true;} + } + return false; + } + + std::string make_inline_array(const array_type& v) const + { + assert(!has_comment_inside(v)); + std::string token; + token += '['; + bool is_first = true; + for(const auto& item : v) + { + if(is_first) {is_first = false;} else {token += ',';} + token += visit(serializer( + (std::numeric_limits::max)(), this->float_prec_, + /* inlined */ true, /*no comment*/ false, /*keys*/ {}, + /*has_comment*/ !item.comments().empty()), item); + } + token += ']'; + return token; + } + + std::string make_inline_table(const table_type& v) const + { + assert(!has_comment_inside(v)); + assert(this->can_be_inlined_); + std::string token; + token += '{'; + bool is_first = true; + for(const auto& kv : v) + { + // in inline tables, trailing comma is not allowed (toml-lang #569). + if(is_first) {is_first = false;} else {token += ',';} + token += format_key(kv.first); + token += '='; + token += visit(serializer( + (std::numeric_limits::max)(), this->float_prec_, + /* inlined */ true, /*no comment*/ false, /*keys*/ {}, + /*has_comment*/ !kv.second.comments().empty()), kv.second); + } + token += '}'; + return token; + } + + std::string make_multiline_table(const table_type& v) const + { + std::string token; + + // print non-table elements first. + // ```toml + // [foo] # a table we're writing now here + // key = "value" # <- non-table element, "key" + // # ... + // [foo.bar] # <- table element, "bar" + // ``` + // because after printing [foo.bar], the remaining non-table values will + // be assigned into [foo.bar], not [foo]. Those values should be printed + // earlier. + for(const auto& kv : v) + { + if(kv.second.is_table() || is_array_of_tables(kv.second)) + { + continue; + } + + token += write_comments(kv.second); + + const auto key_and_sep = format_key(kv.first) + " = "; + const auto residual_width = (this->width_ > key_and_sep.size()) ? + this->width_ - key_and_sep.size() : 0; + token += key_and_sep; + token += visit(serializer(residual_width, this->float_prec_, + /*can be inlined*/ true, /*no comment*/ false, /*keys*/ {}, + /*has_comment*/ !kv.second.comments().empty()), kv.second); + + if(token.back() != '\n') + { + token += '\n'; + } + } + + // normal tables / array of tables + + // after multiline table appeared, the other tables cannot be inline + // because the table would be assigned into the table. + // [foo] + // ... + // bar = {...} # <- bar will be a member of [foo]. + bool multiline_table_printed = false; + for(const auto& kv : v) + { + if(!kv.second.is_table() && !is_array_of_tables(kv.second)) + { + continue; // other stuff are already serialized. skip them. + } + + std::vector ks(this->keys_); + ks.push_back(kv.first); + + auto tmp = visit(serializer(this->width_, this->float_prec_, + !multiline_table_printed, this->no_comment_, ks, + /*has_comment*/ !kv.second.comments().empty()), kv.second); + + // If it is the first time to print a multi-line table, it would be + // helpful to separate normal key-value pair and subtables by a + // newline. + // (this checks if the current key-value pair contains newlines. + // but it is not perfect because multi-line string can also contain + // a newline. in such a case, an empty line will be written) TODO + if((!multiline_table_printed) && + std::find(tmp.cbegin(), tmp.cend(), '\n') != tmp.cend()) + { + multiline_table_printed = true; + token += '\n'; // separate key-value pairs and subtables + + token += write_comments(kv.second); + token += tmp; + + // care about recursive tables (all tables in each level prints + // newline and there will be a full of newlines) + if(tmp.substr(tmp.size() - 2, 2) != "\n\n" && + tmp.substr(tmp.size() - 4, 4) != "\r\n\r\n" ) + { + token += '\n'; + } + } + else + { + token += write_comments(kv.second); + token += tmp; + token += '\n'; + } + } + return token; + } + + std::string make_array_of_tables(const array_type& v) const + { + // if it's not inlined, we need to add `[[table.key]]`. + // but if it can be inlined, we can format it as the following. + // ``` + // table.key = [ + // {...}, + // # comment + // {...}, + // ] + // ``` + // This function checks if inlinization is possible or not, and then + // format the array-of-tables in a proper way. + // + // Note about comments: + // + // If the array itself has a comment (value_has_comment_ == true), we + // should try to make it inline. + // ```toml + // # comment about array + // array = [ + // # comment about table element + // {of = "table"} + // ] + // ``` + // If it is formatted as a multiline table, the two comments becomes + // indistinguishable. + // ```toml + // # comment about array + // # comment about table element + // [[array]] + // of = "table" + // ``` + // So we need to try to make it inline, and it force-inlines regardless + // of the line width limit. + // It may fail if the element of a table has comment. In that case, + // the array-of-tables will be formatted as a multiline table. + if(this->can_be_inlined_ || this->value_has_comment_) + { + std::string token; + if(!keys_.empty()) + { + token += format_key(keys_.back()); + token += " = "; + } + + bool failed = false; + token += "[\n"; + for(const auto& item : v) + { + // if an element of the table has a comment, the table + // cannot be inlined. + if(this->has_comment_inside(item.as_table())) + { + failed = true; + break; + } + // write comments for the table itself + token += write_comments(item); + + const auto t = this->make_inline_table(item.as_table()); + + if(t.size() + 1 > width_ || // +1 for the last comma {...}, + std::find(t.cbegin(), t.cend(), '\n') != t.cend()) + { + // if the value itself has a comment, ignore the line width limit + if( ! this->value_has_comment_) + { + failed = true; + break; + } + } + token += t; + token += ",\n"; + } + + if( ! failed) + { + token += "]\n"; + return token; + } + // if failed, serialize them as [[array.of.tables]]. + } + + std::string token; + for(const auto& item : v) + { + token += write_comments(item); + token += "[["; + token += format_keys(keys_); + token += "]]\n"; + token += this->make_multiline_table(item.as_table()); + } + return token; + } + + std::string write_comments(const value_type& v) const + { + std::string retval; + if(this->no_comment_) {return retval;} + + for(const auto& c : v.comments()) + { + retval += '#'; + retval += c; + retval += '\n'; + } + return retval; + } + + bool is_array_of_tables(const value_type& v) const + { + if(!v.is_array() || v.as_array().empty()) {return false;} + return is_array_of_tables(v.as_array()); + } + bool is_array_of_tables(const array_type& v) const + { + // Since TOML v0.5.0, heterogeneous arrays are allowed. So we need to + // check all the element in an array to check if the array is an array + // of tables. + return std::all_of(v.begin(), v.end(), [](const value_type& elem) { + return elem.is_table(); + }); + } + + private: + + bool can_be_inlined_; + bool no_comment_; + bool value_has_comment_; + int float_prec_; + std::size_t width_; + std::vector keys_; +}; + +template class M, template class V> +std::string +format(const basic_value& v, std::size_t w = 80u, + int fprec = std::numeric_limits::max_digits10, + bool no_comment = false, bool force_inline = false) +{ + using value_type = basic_value; + // if value is a table, it is considered to be a root object. + // the root object can't be an inline table. + if(v.is_table()) + { + std::ostringstream oss; + if(!v.comments().empty()) + { + oss << v.comments(); + oss << '\n'; // to split the file comment from the first element + } + const auto serialized = visit(serializer(w, fprec, false, no_comment), v); + oss << serialized; + return oss.str(); + } + return visit(serializer(w, fprec, force_inline), v); +} + +namespace detail +{ +template +int comment_index(std::basic_ostream&) +{ + static const int index = std::ios_base::xalloc(); + return index; +} +} // detail + +template +std::basic_ostream& +nocomment(std::basic_ostream& os) +{ + // by default, it is zero. and by default, it shows comments. + os.iword(detail::comment_index(os)) = 1; + return os; +} + +template +std::basic_ostream& +showcomment(std::basic_ostream& os) +{ + // by default, it is zero. and by default, it shows comments. + os.iword(detail::comment_index(os)) = 0; + return os; +} + +template class M, template class V> +std::basic_ostream& +operator<<(std::basic_ostream& os, const basic_value& v) +{ + using value_type = basic_value; + + // get status of std::setw(). + const auto w = static_cast(os.width()); + const int fprec = static_cast(os.precision()); + os.width(0); + + // by default, iword is initialized by 0. And by default, toml11 outputs + // comments. So `0` means showcomment. 1 means nocommnet. + const bool no_comment = (1 == os.iword(detail::comment_index(os))); + + if(!no_comment && v.is_table() && !v.comments().empty()) + { + os << v.comments(); + os << '\n'; // to split the file comment from the first element + } + // the root object can't be an inline table. so pass `false`. + const auto serialized = visit(serializer(w, fprec, no_comment, false), v); + os << serialized; + + // if v is a non-table value, and has only one comment, then + // put a comment just after a value. in the following way. + // + // ```toml + // key = "value" # comment. + // ``` + // + // Since the top-level toml object is a table, one who want to put a + // non-table toml value must use this in a following way. + // + // ```cpp + // toml::value v; + // std::cout << "user-defined-key = " << v << std::endl; + // ``` + // + // In this case, it is impossible to put comments before key-value pair. + // The only way to preserve comments is to put all of them after a value. + if(!no_comment && !v.is_table() && !v.comments().empty()) + { + os << " #"; + for(const auto& c : v.comments()) {os << c;} + } + return os; +} + +} // toml +#endif// TOML11_SERIALIZER_HPP diff --git a/external/toml11/toml/source_location.hpp b/external/toml11/toml/source_location.hpp new file mode 100644 index 0000000..135024f --- /dev/null +++ b/external/toml11/toml/source_location.hpp @@ -0,0 +1,239 @@ +// Copyright Toru Niina 2019. +// Distributed under the MIT License. +#ifndef TOML11_SOURCE_LOCATION_HPP +#define TOML11_SOURCE_LOCATION_HPP +#include +#include + +#include "region.hpp" + +namespace toml +{ + +// A struct to contain location in a toml file. +// The interface imitates std::experimental::source_location, +// but not completely the same. +// +// It would be constructed by toml::value. It can be used to generate +// user-defined error messages. +// +// - std::uint_least32_t line() const noexcept +// - returns the line number where the region is on. +// - std::uint_least32_t column() const noexcept +// - returns the column number where the region starts. +// - std::uint_least32_t region() const noexcept +// - returns the size of the region. +// +// +-- line() +-- region of interest (region() == 9) +// v .---+---. +// 12 | value = "foo bar" +// ^ +// +-- column() +// +// - std::string const& file_name() const noexcept; +// - name of the file. +// - std::string const& line_str() const noexcept; +// - the whole line that contains the region of interest. +// +struct source_location +{ + public: + + source_location() + : line_num_(1), column_num_(1), region_size_(1), + file_name_("unknown file"), line_str_("") + {} + + explicit source_location(const detail::region_base* reg) + : line_num_(1), column_num_(1), region_size_(1), + file_name_("unknown file"), line_str_("") + { + if(reg) + { + if(reg->line_num() != detail::region_base().line_num()) + { + line_num_ = static_cast( + std::stoul(reg->line_num())); + } + column_num_ = static_cast(reg->before() + 1); + region_size_ = static_cast(reg->size()); + file_name_ = reg->name(); + line_str_ = reg->line(); + } + } + + explicit source_location(const detail::region& reg) + : line_num_(static_cast(std::stoul(reg.line_num()))), + column_num_(static_cast(reg.before() + 1)), + region_size_(static_cast(reg.size())), + file_name_(reg.name()), + line_str_ (reg.line()) + {} + explicit source_location(const detail::location& loc) + : line_num_(static_cast(std::stoul(loc.line_num()))), + column_num_(static_cast(loc.before() + 1)), + region_size_(static_cast(loc.size())), + file_name_(loc.name()), + line_str_ (loc.line()) + {} + + ~source_location() = default; + source_location(source_location const&) = default; + source_location(source_location &&) = default; + source_location& operator=(source_location const&) = default; + source_location& operator=(source_location &&) = default; + + std::uint_least32_t line() const noexcept {return line_num_;} + std::uint_least32_t column() const noexcept {return column_num_;} + std::uint_least32_t region() const noexcept {return region_size_;} + + std::string const& file_name() const noexcept {return file_name_;} + std::string const& line_str() const noexcept {return line_str_;} + + private: + + std::uint_least32_t line_num_; + std::uint_least32_t column_num_; + std::uint_least32_t region_size_; + std::string file_name_; + std::string line_str_; +}; + +namespace detail +{ + +// internal error message generation. +inline std::string format_underline(const std::string& message, + const std::vector>& loc_com, + const std::vector& helps = {}, + const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED) +{ + std::size_t line_num_width = 0; + for(const auto& lc : loc_com) + { + std::uint_least32_t line = lc.first.line(); + std::size_t digit = 0; + while(line != 0) + { + line /= 10; + digit += 1; + } + line_num_width = (std::max)(line_num_width, digit); + } + // 1 is the minimum width + line_num_width = std::max(line_num_width, 1); + + std::ostringstream retval; + + if(color::should_color() || colorize) + { + retval << color::colorize; // turn on ANSI color + } + + // XXX + // Here, before `colorize` support, it does not output `[error]` prefix + // automatically. So some user may output it manually and this change may + // duplicate the prefix. To avoid it, check the first 7 characters and + // if it is "[error]", it removes that part from the message shown. + if(message.size() > 7 && message.substr(0, 7) == "[error]") + { + retval +#ifndef TOML11_NO_ERROR_PREFIX + << color::bold << color::red << "[error]" << color::reset +#endif + << color::bold << message.substr(7) << color::reset << '\n'; + } + else + { + retval +#ifndef TOML11_NO_ERROR_PREFIX + << color::bold << color::red << "[error] " << color::reset +#endif + << color::bold << message << color::reset << '\n'; + } + + const auto format_one_location = [line_num_width] + (std::ostringstream& oss, + const source_location& loc, const std::string& comment) -> void + { + oss << ' ' << color::bold << color::blue + << std::setw(static_cast(line_num_width)) + << std::right << loc.line() << " | " << color::reset + << loc.line_str() << '\n'; + + oss << make_string(line_num_width + 1, ' ') + << color::bold << color::blue << " | " << color::reset + << make_string(loc.column()-1 /*1-origin*/, ' '); + + if(loc.region() == 1) + { + // invalid + // ^------ + oss << color::bold << color::red << "^---" << color::reset; + } + else + { + // invalid + // ~~~~~~~ + const auto underline_len = (std::min)( + static_cast(loc.region()), loc.line_str().size()); + oss << color::bold << color::red + << make_string(underline_len, '~') << color::reset; + } + oss << ' '; + oss << comment; + return; + }; + + assert(!loc_com.empty()); + + // --> example.toml + // | + retval << color::bold << color::blue << " --> " << color::reset + << loc_com.front().first.file_name() << '\n'; + retval << make_string(line_num_width + 1, ' ') + << color::bold << color::blue << " |\n" << color::reset; + // 1 | key value + // | ^--- missing = + format_one_location(retval, loc_com.front().first, loc_com.front().second); + + // process the rest of the locations + for(std::size_t i=1; i filename.toml" again + { + retval << color::bold << color::blue << " --> " << color::reset + << curr.first.file_name() << '\n'; + retval << make_string(line_num_width + 1, ' ') + << color::bold << color::blue << " |\n" << color::reset; + } + + format_one_location(retval, curr.first, curr.second); + } + + if(!helps.empty()) + { + retval << '\n'; + retval << make_string(line_num_width + 1, ' '); + retval << color::bold << color::blue << " |" << color::reset; + for(const auto& help : helps) + { + retval << color::bold << "\nHint: " << color::reset; + retval << help; + } + } + return retval.str(); +} + +} // detail +} // toml +#endif// TOML11_SOURCE_LOCATION_HPP diff --git a/external/toml11/toml/storage.hpp b/external/toml11/toml/storage.hpp new file mode 100644 index 0000000..202f903 --- /dev/null +++ b/external/toml11/toml/storage.hpp @@ -0,0 +1,43 @@ +// Copyright Toru Niina 2017. +// Distributed under the MIT License. +#ifndef TOML11_STORAGE_HPP +#define TOML11_STORAGE_HPP +#include "utility.hpp" + +namespace toml +{ +namespace detail +{ + +// this contains pointer and deep-copy the content if copied. +// to avoid recursive pointer. +template +struct storage +{ + using value_type = T; + + explicit storage(value_type const& v): ptr(toml::make_unique(v)) {} + explicit storage(value_type&& v): ptr(toml::make_unique(std::move(v))) {} + ~storage() = default; + storage(const storage& rhs): ptr(toml::make_unique(*rhs.ptr)) {} + storage& operator=(const storage& rhs) + { + this->ptr = toml::make_unique(*rhs.ptr); + return *this; + } + storage(storage&&) = default; + storage& operator=(storage&&) = default; + + bool is_ok() const noexcept {return static_cast(ptr);} + + value_type& value() & noexcept {return *ptr;} + value_type const& value() const& noexcept {return *ptr;} + value_type&& value() && noexcept {return std::move(*ptr);} + + private: + std::unique_ptr ptr; +}; + +} // detail +} // toml +#endif// TOML11_STORAGE_HPP diff --git a/external/toml11/toml/string.hpp b/external/toml11/toml/string.hpp new file mode 100644 index 0000000..def3e57 --- /dev/null +++ b/external/toml11/toml/string.hpp @@ -0,0 +1,228 @@ +// Copyright Toru Niina 2017. +// Distributed under the MIT License. +#ifndef TOML11_STRING_HPP +#define TOML11_STRING_HPP + +#include "version.hpp" + +#include + +#include +#include + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L +#if __has_include() +#define TOML11_USING_STRING_VIEW 1 +#include +#endif +#endif + +namespace toml +{ + +enum class string_t : std::uint8_t +{ + basic = 0, + literal = 1, +}; + +struct string +{ + string() = default; + ~string() = default; + string(const string& s) = default; + string(string&& s) = default; + string& operator=(const string& s) = default; + string& operator=(string&& s) = default; + + string(const std::string& s): kind(string_t::basic), str(s){} + string(const std::string& s, string_t k): kind(k), str(s){} + string(const char* s): kind(string_t::basic), str(s){} + string(const char* s, string_t k): kind(k), str(s){} + + string(std::string&& s): kind(string_t::basic), str(std::move(s)){} + string(std::string&& s, string_t k): kind(k), str(std::move(s)){} + + string& operator=(const std::string& s) + {kind = string_t::basic; str = s; return *this;} + string& operator=(std::string&& s) + {kind = string_t::basic; str = std::move(s); return *this;} + + operator std::string& () & noexcept {return str;} + operator std::string const& () const& noexcept {return str;} + operator std::string&& () && noexcept {return std::move(str);} + + string& operator+=(const char* rhs) {str += rhs; return *this;} + string& operator+=(const char rhs) {str += rhs; return *this;} + string& operator+=(const std::string& rhs) {str += rhs; return *this;} + string& operator+=(const string& rhs) {str += rhs.str; return *this;} + +#if defined(TOML11_USING_STRING_VIEW) && TOML11_USING_STRING_VIEW>0 + explicit string(std::string_view s): kind(string_t::basic), str(s){} + string(std::string_view s, string_t k): kind(k), str(s){} + + string& operator=(std::string_view s) + {kind = string_t::basic; str = s; return *this;} + + explicit operator std::string_view() const noexcept + {return std::string_view(str);} + + string& operator+=(const std::string_view& rhs) {str += rhs; return *this;} +#endif + + string_t kind; + std::string str; +}; + +inline bool operator==(const string& lhs, const string& rhs) +{ + return lhs.kind == rhs.kind && lhs.str == rhs.str; +} +inline bool operator!=(const string& lhs, const string& rhs) +{ + return !(lhs == rhs); +} +inline bool operator<(const string& lhs, const string& rhs) +{ + return (lhs.kind == rhs.kind) ? (lhs.str < rhs.str) : (lhs.kind < rhs.kind); +} +inline bool operator>(const string& lhs, const string& rhs) +{ + return rhs < lhs; +} +inline bool operator<=(const string& lhs, const string& rhs) +{ + return !(rhs < lhs); +} +inline bool operator>=(const string& lhs, const string& rhs) +{ + return !(lhs < rhs); +} + +inline bool +operator==(const string& lhs, const std::string& rhs) {return lhs.str == rhs;} +inline bool +operator!=(const string& lhs, const std::string& rhs) {return lhs.str != rhs;} +inline bool +operator< (const string& lhs, const std::string& rhs) {return lhs.str < rhs;} +inline bool +operator> (const string& lhs, const std::string& rhs) {return lhs.str > rhs;} +inline bool +operator<=(const string& lhs, const std::string& rhs) {return lhs.str <= rhs;} +inline bool +operator>=(const string& lhs, const std::string& rhs) {return lhs.str >= rhs;} + +inline bool +operator==(const std::string& lhs, const string& rhs) {return lhs == rhs.str;} +inline bool +operator!=(const std::string& lhs, const string& rhs) {return lhs != rhs.str;} +inline bool +operator< (const std::string& lhs, const string& rhs) {return lhs < rhs.str;} +inline bool +operator> (const std::string& lhs, const string& rhs) {return lhs > rhs.str;} +inline bool +operator<=(const std::string& lhs, const string& rhs) {return lhs <= rhs.str;} +inline bool +operator>=(const std::string& lhs, const string& rhs) {return lhs >= rhs.str;} + +inline bool +operator==(const string& lhs, const char* rhs) {return lhs.str == std::string(rhs);} +inline bool +operator!=(const string& lhs, const char* rhs) {return lhs.str != std::string(rhs);} +inline bool +operator< (const string& lhs, const char* rhs) {return lhs.str < std::string(rhs);} +inline bool +operator> (const string& lhs, const char* rhs) {return lhs.str > std::string(rhs);} +inline bool +operator<=(const string& lhs, const char* rhs) {return lhs.str <= std::string(rhs);} +inline bool +operator>=(const string& lhs, const char* rhs) {return lhs.str >= std::string(rhs);} + +inline bool +operator==(const char* lhs, const string& rhs) {return std::string(lhs) == rhs.str;} +inline bool +operator!=(const char* lhs, const string& rhs) {return std::string(lhs) != rhs.str;} +inline bool +operator< (const char* lhs, const string& rhs) {return std::string(lhs) < rhs.str;} +inline bool +operator> (const char* lhs, const string& rhs) {return std::string(lhs) > rhs.str;} +inline bool +operator<=(const char* lhs, const string& rhs) {return std::string(lhs) <= rhs.str;} +inline bool +operator>=(const char* lhs, const string& rhs) {return std::string(lhs) >= rhs.str;} + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const string& s) +{ + if(s.kind == string_t::basic) + { + if(std::find(s.str.cbegin(), s.str.cend(), '\n') != s.str.cend()) + { + // it contains newline. make it multiline string. + os << "\"\"\"\n"; + for(auto i=s.str.cbegin(), e=s.str.cend(); i!=e; ++i) + { + switch(*i) + { + case '\\': {os << "\\\\"; break;} + case '\"': {os << "\\\""; break;} + case '\b': {os << "\\b"; break;} + case '\t': {os << "\\t"; break;} + case '\f': {os << "\\f"; break;} + case '\n': {os << '\n'; break;} + case '\r': + { + // since it is a multiline string, + // CRLF is not needed to be escaped. + if(std::next(i) != e && *std::next(i) == '\n') + { + os << "\r\n"; + ++i; + } + else + { + os << "\\r"; + } + break; + } + default: {os << *i; break;} + } + } + os << "\\\n\"\"\""; + return os; + } + // no newline. make it inline. + os << "\""; + for(const auto c : s.str) + { + switch(c) + { + case '\\': {os << "\\\\"; break;} + case '\"': {os << "\\\""; break;} + case '\b': {os << "\\b"; break;} + case '\t': {os << "\\t"; break;} + case '\f': {os << "\\f"; break;} + case '\n': {os << "\\n"; break;} + case '\r': {os << "\\r"; break;} + default : {os << c; break;} + } + } + os << "\""; + return os; + } + // the string `s` is literal-string. + if(std::find(s.str.cbegin(), s.str.cend(), '\n') != s.str.cend() || + std::find(s.str.cbegin(), s.str.cend(), '\'') != s.str.cend() ) + { + // contains newline or single quote. make it multiline. + os << "'''\n" << s.str << "'''"; + return os; + } + // normal literal string + os << '\'' << s.str << '\''; + return os; +} + +} // toml +#endif// TOML11_STRING_H diff --git a/external/toml11/toml/traits.hpp b/external/toml11/toml/traits.hpp new file mode 100644 index 0000000..255d9e8 --- /dev/null +++ b/external/toml11/toml/traits.hpp @@ -0,0 +1,328 @@ +// Copyright Toru Niina 2017. +// Distributed under the MIT License. +#ifndef TOML11_TRAITS_HPP +#define TOML11_TRAITS_HPP + +#include "from.hpp" +#include "into.hpp" +#include "version.hpp" + +#include +#include +#include +#include +#include +#include + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L +#if __has_include() +#include +#endif // has_include() +#endif // cplusplus >= C++17 + +namespace toml +{ +template class T, template class A> +class basic_value; + +namespace detail +{ +// --------------------------------------------------------------------------- +// check whether type T is a kind of container/map class + +struct has_iterator_impl +{ + template static std::true_type check(typename T::iterator*); + template static std::false_type check(...); +}; +struct has_value_type_impl +{ + template static std::true_type check(typename T::value_type*); + template static std::false_type check(...); +}; +struct has_key_type_impl +{ + template static std::true_type check(typename T::key_type*); + template static std::false_type check(...); +}; +struct has_mapped_type_impl +{ + template static std::true_type check(typename T::mapped_type*); + template static std::false_type check(...); +}; +struct has_reserve_method_impl +{ + template static std::false_type check(...); + template static std::true_type check( + decltype(std::declval().reserve(std::declval()))*); +}; +struct has_push_back_method_impl +{ + template static std::false_type check(...); + template static std::true_type check( + decltype(std::declval().push_back(std::declval()))*); +}; +struct is_comparable_impl +{ + template static std::false_type check(...); + template static std::true_type check( + decltype(std::declval() < std::declval())*); +}; + +struct has_from_toml_method_impl +{ + template class Tb, template class A> + static std::true_type check( + decltype(std::declval().from_toml( + std::declval<::toml::basic_value>()))*); + + template class Tb, template class A> + static std::false_type check(...); +}; +struct has_into_toml_method_impl +{ + template + static std::true_type check(decltype(std::declval().into_toml())*); + template + static std::false_type check(...); +}; + +struct has_specialized_from_impl +{ + template + static std::false_type check(...); + template)> + static std::true_type check(::toml::from*); +}; +struct has_specialized_into_impl +{ + template + static std::false_type check(...); + template)> + static std::true_type check(::toml::from*); +}; + + +/// Intel C++ compiler can not use decltype in parent class declaration, here +/// is a hack to work around it. https://stackoverflow.com/a/23953090/4692076 +#ifdef __INTEL_COMPILER +#define decltype(...) std::enable_if::type +#endif + +template +struct has_iterator : decltype(has_iterator_impl::check(nullptr)){}; +template +struct has_value_type : decltype(has_value_type_impl::check(nullptr)){}; +template +struct has_key_type : decltype(has_key_type_impl::check(nullptr)){}; +template +struct has_mapped_type : decltype(has_mapped_type_impl::check(nullptr)){}; +template +struct has_reserve_method : decltype(has_reserve_method_impl::check(nullptr)){}; +template +struct has_push_back_method : decltype(has_push_back_method_impl::check(nullptr)){}; +template +struct is_comparable : decltype(is_comparable_impl::check(nullptr)){}; + +template class Tb, template class A> +struct has_from_toml_method +: decltype(has_from_toml_method_impl::check(nullptr)){}; + +template +struct has_into_toml_method +: decltype(has_into_toml_method_impl::check(nullptr)){}; + +template +struct has_specialized_from : decltype(has_specialized_from_impl::check(nullptr)){}; +template +struct has_specialized_into : decltype(has_specialized_into_impl::check(nullptr)){}; + +#ifdef __INTEL_COMPILER +#undef decltype +#endif + +// --------------------------------------------------------------------------- +// C++17 and/or/not + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L + +using std::conjunction; +using std::disjunction; +using std::negation; + +#else + +template struct conjunction : std::true_type{}; +template struct conjunction : T{}; +template +struct conjunction : + std::conditional(T::value), conjunction, T>::type +{}; + +template struct disjunction : std::false_type{}; +template struct disjunction : T {}; +template +struct disjunction : + std::conditional(T::value), T, disjunction>::type +{}; + +template +struct negation : std::integral_constant(T::value)>{}; + +#endif + +// --------------------------------------------------------------------------- +// type checkers + +template struct is_std_pair : std::false_type{}; +template +struct is_std_pair> : std::true_type{}; + +template struct is_std_tuple : std::false_type{}; +template +struct is_std_tuple> : std::true_type{}; + +template struct is_std_forward_list : std::false_type{}; +template +struct is_std_forward_list> : std::true_type{}; + +template struct is_chrono_duration: std::false_type{}; +template +struct is_chrono_duration>: std::true_type{}; + +template +struct is_map : conjunction< // map satisfies all the following conditions + has_iterator, // has T::iterator + has_value_type, // has T::value_type + has_key_type, // has T::key_type + has_mapped_type // has T::mapped_type + >{}; +template struct is_map : is_map{}; +template struct is_map : is_map{}; +template struct is_map : is_map{}; +template struct is_map : is_map{}; + +template +struct is_container : conjunction< + negation>, // not a map + negation>, // not a std::string +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L +#if __has_include() + negation>, // not a std::string_view +#endif // has_include() +#endif + has_iterator, // has T::iterator + has_value_type // has T::value_type + >{}; +template struct is_container : is_container{}; +template struct is_container : is_container{}; +template struct is_container : is_container{}; +template struct is_container : is_container{}; + +template +struct is_basic_value: std::false_type{}; +template struct is_basic_value : is_basic_value{}; +template struct is_basic_value : is_basic_value{}; +template struct is_basic_value : is_basic_value{}; +template struct is_basic_value : is_basic_value{}; +template class M, template class V> +struct is_basic_value<::toml::basic_value>: std::true_type{}; + +// --------------------------------------------------------------------------- +// C++14 index_sequence + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201402L + +using std::index_sequence; +using std::make_index_sequence; + +#else + +template struct index_sequence{}; + +template struct push_back_index_sequence{}; +template +struct push_back_index_sequence, N> +{ + typedef index_sequence type; +}; + +template +struct index_sequence_maker +{ + typedef typename push_back_index_sequence< + typename index_sequence_maker::type, N>::type type; +}; +template<> +struct index_sequence_maker<0> +{ + typedef index_sequence<0> type; +}; +template +using make_index_sequence = typename index_sequence_maker::type; + +#endif // cplusplus >= 2014 + +// --------------------------------------------------------------------------- +// C++14 enable_if_t + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201402L + +using std::enable_if_t; + +#else + +template +using enable_if_t = typename std::enable_if::type; + +#endif // cplusplus >= 2014 + +// --------------------------------------------------------------------------- +// return_type_of_t + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L && defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable>=201703 + +template +using return_type_of_t = std::invoke_result_t; + +#else +// result_of is deprecated after C++17 +template +using return_type_of_t = typename std::result_of::type; + +#endif + +// --------------------------------------------------------------------------- +// is_string_literal +// +// to use this, pass `typename remove_reference::type` to T. + +template +struct is_string_literal: +disjunction< + std::is_same, + conjunction< + std::is_array, + std::is_same::type> + > + >{}; + +// --------------------------------------------------------------------------- +// C++20 remove_cvref_t + +template +struct remove_cvref +{ + using type = typename std::remove_cv< + typename std::remove_reference::type>::type; +}; + +template +using remove_cvref_t = typename remove_cvref::type; + +}// detail +}//toml +#endif // TOML_TRAITS diff --git a/external/toml11/toml/types.hpp b/external/toml11/toml/types.hpp new file mode 100644 index 0000000..1e420e7 --- /dev/null +++ b/external/toml11/toml/types.hpp @@ -0,0 +1,173 @@ +// Copyright Toru Niina 2017. +// Distributed under the MIT License. +#ifndef TOML11_TYPES_HPP +#define TOML11_TYPES_HPP +#include +#include + +#include "comments.hpp" +#include "datetime.hpp" +#include "string.hpp" +#include "traits.hpp" + +namespace toml +{ + +template class Table, // map-like class + template class Array> // vector-like class +class basic_value; + +using character = char; +using key = std::string; + +#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ <= 4 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +using boolean = bool; +using integer = std::int64_t; +using floating = double; // "float" is a keyword, cannot use it here. +// the following stuffs are structs defined here, so aliases are not needed. +// - string +// - offset_datetime +// - offset_datetime +// - local_datetime +// - local_date +// - local_time + +#if defined(__GNUC__) && !defined(__clang__) +# pragma GCC diagnostic pop +#endif + +// default toml::value and default array/table. these are defined after defining +// basic_value itself. +// using value = basic_value; +// using array = typename value::array_type; +// using table = typename value::table_type; + +// to avoid warnings about `value_t::integer` is "shadowing" toml::integer in +// GCC -Wshadow=global. +#if defined(__GNUC__) && !defined(__clang__) +# pragma GCC diagnostic push +# if 7 <= __GNUC__ +# pragma GCC diagnostic ignored "-Wshadow=global" +# else // gcc-6 or older +# pragma GCC diagnostic ignored "-Wshadow" +# endif +#endif +enum class value_t : std::uint8_t +{ + empty = 0, + boolean = 1, + integer = 2, + floating = 3, + string = 4, + offset_datetime = 5, + local_datetime = 6, + local_date = 7, + local_time = 8, + array = 9, + table = 10, +}; +#if defined(__GNUC__) && !defined(__clang__) +# pragma GCC diagnostic pop +#endif + +template +inline std::basic_ostream& +operator<<(std::basic_ostream& os, value_t t) +{ + switch(t) + { + case value_t::boolean : os << "boolean"; return os; + case value_t::integer : os << "integer"; return os; + case value_t::floating : os << "floating"; return os; + case value_t::string : os << "string"; return os; + case value_t::offset_datetime : os << "offset_datetime"; return os; + case value_t::local_datetime : os << "local_datetime"; return os; + case value_t::local_date : os << "local_date"; return os; + case value_t::local_time : os << "local_time"; return os; + case value_t::array : os << "array"; return os; + case value_t::table : os << "table"; return os; + case value_t::empty : os << "empty"; return os; + default : os << "unknown"; return os; + } +} + +template, + typename alloc = std::allocator> +inline std::basic_string stringize(value_t t) +{ + std::basic_ostringstream oss; + oss << t; + return oss.str(); +} + +namespace detail +{ + +// helper to define a type that represents a value_t value. +template +using value_t_constant = std::integral_constant; + +// meta-function that convertes from value_t to the exact toml type that corresponds to. +// It takes toml::basic_value type because array and table types depend on it. +template struct enum_to_type {using type = void ;}; +template struct enum_to_type{using type = void ;}; +template struct enum_to_type{using type = boolean ;}; +template struct enum_to_type{using type = integer ;}; +template struct enum_to_type{using type = floating ;}; +template struct enum_to_type{using type = string ;}; +template struct enum_to_type{using type = offset_datetime ;}; +template struct enum_to_type{using type = local_datetime ;}; +template struct enum_to_type{using type = local_date ;}; +template struct enum_to_type{using type = local_time ;}; +template struct enum_to_type{using type = typename Value::array_type;}; +template struct enum_to_type{using type = typename Value::table_type;}; + +// meta-function that converts from an exact toml type to the enum that corresponds to. +template +struct type_to_enum : std::conditional< + std::is_same::value, // if T == array_type, + value_t_constant, // then value_t::array + typename std::conditional< // else... + std::is_same::value, // if T == table_type + value_t_constant, // then value_t::table + value_t_constant // else value_t::empty + >::type + >::type {}; +template struct type_to_enum: value_t_constant {}; +template struct type_to_enum: value_t_constant {}; +template struct type_to_enum: value_t_constant {}; +template struct type_to_enum: value_t_constant {}; +template struct type_to_enum: value_t_constant {}; +template struct type_to_enum: value_t_constant {}; +template struct type_to_enum: value_t_constant {}; +template struct type_to_enum: value_t_constant {}; + +// meta-function that checks the type T is the same as one of the toml::* types. +template +struct is_exact_toml_type : disjunction< + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same + >{}; +template struct is_exact_toml_type : is_exact_toml_type{}; +template struct is_exact_toml_type : is_exact_toml_type{}; +template struct is_exact_toml_type : is_exact_toml_type{}; +template struct is_exact_toml_type: is_exact_toml_type{}; + +} // detail +} // toml + +#endif// TOML11_TYPES_H diff --git a/external/toml11/toml/utility.hpp b/external/toml11/toml/utility.hpp new file mode 100644 index 0000000..53a18b9 --- /dev/null +++ b/external/toml11/toml/utility.hpp @@ -0,0 +1,150 @@ +// Copyright Toru Niina 2017. +// Distributed under the MIT License. +#ifndef TOML11_UTILITY_HPP +#define TOML11_UTILITY_HPP +#include +#include +#include + +#include "traits.hpp" +#include "version.hpp" + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201402L +# define TOML11_MARK_AS_DEPRECATED(msg) [[deprecated(msg)]] +#elif defined(__GNUC__) +# define TOML11_MARK_AS_DEPRECATED(msg) __attribute__((deprecated(msg))) +#elif defined(_MSC_VER) +# define TOML11_MARK_AS_DEPRECATED(msg) __declspec(deprecated(msg)) +#else +# define TOML11_MARK_AS_DEPRECATED +#endif + +namespace toml +{ + +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201402L + +using std::make_unique; + +#else + +template +inline std::unique_ptr make_unique(Ts&& ... args) +{ + return std::unique_ptr(new T(std::forward(args)...)); +} + +#endif // TOML11_CPLUSPLUS_STANDARD_VERSION >= 2014 + +namespace detail +{ +template +void try_reserve_impl(Container& container, std::size_t N, std::true_type) +{ + container.reserve(N); + return; +} +template +void try_reserve_impl(Container&, std::size_t, std::false_type) noexcept +{ + return; +} +} // detail + +template +void try_reserve(Container& container, std::size_t N) +{ + if(N <= container.size()) {return;} + detail::try_reserve_impl(container, N, detail::has_reserve_method{}); + return; +} + +namespace detail +{ +inline std::string concat_to_string_impl(std::ostringstream& oss) +{ + return oss.str(); +} +template +std::string concat_to_string_impl(std::ostringstream& oss, T&& head, Ts&& ... tail) +{ + oss << std::forward(head); + return concat_to_string_impl(oss, std::forward(tail) ... ); +} +} // detail + +template +std::string concat_to_string(Ts&& ... args) +{ + std::ostringstream oss; + oss << std::boolalpha << std::fixed; + return detail::concat_to_string_impl(oss, std::forward(args) ...); +} + +template +T from_string(const std::string& str, T opt) +{ + T v(opt); + std::istringstream iss(str); + iss >> v; + return v; +} + +namespace detail +{ +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201402L +template +decltype(auto) last_one(T&& tail) noexcept +{ + return std::forward(tail); +} + +template +decltype(auto) last_one(T&& /*head*/, Ts&& ... tail) noexcept +{ + return last_one(std::forward(tail)...); +} +#else // C++11 +// The following code +// ```cpp +// 1 | template +// 2 | auto last_one(T&& /*head*/, Ts&& ... tail) +// 3 | -> decltype(last_one(std::forward(tail)...)) +// 4 | { +// 5 | return last_one(std::forward(tail)...); +// 6 | } +// ``` +// does not work because the function `last_one(...)` is not yet defined at +// line #3, so `decltype()` cannot deduce the type returned from `last_one`. +// So we need to determine return type in a different way, like a meta func. + +template +struct last_one_in_pack +{ + using type = typename last_one_in_pack::type; +}; +template +struct last_one_in_pack +{ + using type = T; +}; +template +using last_one_in_pack_t = typename last_one_in_pack::type; + +template +T&& last_one(T&& tail) noexcept +{ + return std::forward(tail); +} +template +enable_if_t<(sizeof...(Ts) > 0), last_one_in_pack_t> +last_one(T&& /*head*/, Ts&& ... tail) +{ + return last_one(std::forward(tail)...); +} + +#endif +} // detail + +}// toml +#endif // TOML11_UTILITY diff --git a/external/toml11/toml/value.hpp b/external/toml11/toml/value.hpp new file mode 100644 index 0000000..d57ab80 --- /dev/null +++ b/external/toml11/toml/value.hpp @@ -0,0 +1,2037 @@ +// Copyright Toru Niina 2017. +// Distributed under the MIT License. +#ifndef TOML11_VALUE_HPP +#define TOML11_VALUE_HPP +#include + +#include "comments.hpp" +#include "exception.hpp" +#include "into.hpp" +#include "region.hpp" +#include "source_location.hpp" +#include "storage.hpp" +#include "traits.hpp" +#include "types.hpp" +#include "utility.hpp" + +namespace toml +{ + +namespace detail +{ + +// to show error messages. not recommended for users. +template +inline region_base const* get_region(const Value& v) +{ + return v.region_info_.get(); +} + +template +void change_region(Value& v, region reg) +{ + v.region_info_ = std::make_shared(std::move(reg)); + return; +} + +template +[[noreturn]] inline void +throw_bad_cast(const std::string& funcname, value_t actual, const Value& v) +{ + throw type_error(detail::format_underline( + concat_to_string(funcname, "bad_cast to ", Expected), { + {v.location(), concat_to_string("the actual type is ", actual)} + }), v.location()); +} + +// Throw `out_of_range` from `toml::value::at()` and `toml::find()` +// after generating an error message. +// +// The implementation is a bit complicated and there are many edge-cases. +// If you are not interested in the error message generation, just skip this. +template +[[noreturn]] void +throw_key_not_found_error(const Value& v, const key& ky) +{ + // The top-level table has its region at the first character of the file. + // That means that, in the case when a key is not found in the top-level + // table, the error message points to the first character. If the file has + // its first table at the first line, the error message would be like this. + // ```console + // [error] key "a" not found + // --> example.toml + // | + // 1 | [table] + // | ^------ in this table + // ``` + // It actually points to the top-level table at the first character, + // not `[table]`. But it is too confusing. To avoid the confusion, the error + // message should explicitly say "key not found in the top-level table", + // or "the parsed file is empty" if there is no content at all (0 bytes in file). + const auto loc = v.location(); + if(loc.line() == 1 && loc.region() == 0) + { + // First line with a zero-length region means "empty file". + // The region will be generated at `parse_toml_file` function + // if the file contains no bytes. + throw std::out_of_range(format_underline(concat_to_string( + "key \"", ky, "\" not found in the top-level table"), { + {loc, "the parsed file is empty"} + })); + } + else if(loc.line() == 1 && loc.region() == 1) + { + // Here it assumes that top-level table starts at the first character. + // The region corresponds to the top-level table will be generated at + // `parse_toml_file` function. + // It also assumes that the top-level table size is just one and + // the line number is `1`. It is always satisfied. And those conditions + // are satisfied only if the table is the top-level table. + // + // 1. one-character dot-key at the first line + // ```toml + // a.b = "c" + // ``` + // toml11 counts whole key as the table key. Here, `a.b` is the region + // of the table "a". It could be counter intuitive, but it works. + // The size of the region is 3, not 1. The above example is the shortest + // dot-key example. The size cannot be 1. + // + // 2. one-character inline-table at the first line + // ```toml + // a = {b = "c"} + // ``` + // toml11 considers the inline table body as the table region. Here, + // `{b = "c"}` is the region of the table "a". The size of the region + // is 9, not 1. The shotest inline table still has two characters, `{` + // and `}`. The size cannot be 1. + // + // 3. one-character table declaration at the first line + // ```toml + // [a] + // ``` + // toml11 considers the whole table key as the table region. Here, + // `[a]` is the table region. The size is 3, not 1. + // + throw std::out_of_range(format_underline(concat_to_string( + "key \"", ky, "\" not found in the top-level table"), { + {loc, "the top-level table starts here"} + })); + } + else + { + // normal table. + throw std::out_of_range(format_underline(concat_to_string( + "key \"", ky, "\" not found"), { {loc, "in this table"} })); + } +} + +// switch by `value_t` at the compile time. +template +struct switch_cast {}; +#define TOML11_GENERATE_SWITCH_CASTER(TYPE) \ + template<> \ + struct switch_cast \ + { \ + template \ + static typename Value::TYPE##_type& invoke(Value& v) \ + { \ + return v.as_##TYPE(); \ + } \ + template \ + static typename Value::TYPE##_type const& invoke(const Value& v) \ + { \ + return v.as_##TYPE(); \ + } \ + template \ + static typename Value::TYPE##_type&& invoke(Value&& v) \ + { \ + return std::move(v).as_##TYPE(); \ + } \ + }; \ + /**/ +TOML11_GENERATE_SWITCH_CASTER(boolean) +TOML11_GENERATE_SWITCH_CASTER(integer) +TOML11_GENERATE_SWITCH_CASTER(floating) +TOML11_GENERATE_SWITCH_CASTER(string) +TOML11_GENERATE_SWITCH_CASTER(offset_datetime) +TOML11_GENERATE_SWITCH_CASTER(local_datetime) +TOML11_GENERATE_SWITCH_CASTER(local_date) +TOML11_GENERATE_SWITCH_CASTER(local_time) +TOML11_GENERATE_SWITCH_CASTER(array) +TOML11_GENERATE_SWITCH_CASTER(table) + +#undef TOML11_GENERATE_SWITCH_CASTER + +}// detail + +template class Table = std::unordered_map, + template class Array = std::vector> +class basic_value +{ + template + static void assigner(T& dst, U&& v) + { + const auto tmp = ::new(std::addressof(dst)) T(std::forward(v)); + assert(tmp == std::addressof(dst)); + (void)tmp; + } + + using region_base = detail::region_base; + + template class T, + template class A> + friend class basic_value; + + public: + + using comment_type = Comment; + using key_type = ::toml::key; + using value_type = basic_value; + using boolean_type = ::toml::boolean; + using integer_type = ::toml::integer; + using floating_type = ::toml::floating; + using string_type = ::toml::string; + using local_time_type = ::toml::local_time; + using local_date_type = ::toml::local_date; + using local_datetime_type = ::toml::local_datetime; + using offset_datetime_type = ::toml::offset_datetime; + using array_type = Array; + using table_type = Table; + + public: + + basic_value() noexcept + : type_(value_t::empty), + region_info_(std::make_shared(region_base{})) + {} + ~basic_value() noexcept {this->cleanup();} + + basic_value(const basic_value& v) + : type_(v.type()), region_info_(v.region_info_), comments_(v.comments_) + { + switch(v.type()) + { + case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; + case value_t::integer : assigner(integer_ , v.integer_ ); break; + case value_t::floating : assigner(floating_ , v.floating_ ); break; + case value_t::string : assigner(string_ , v.string_ ); break; + case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; + case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; + case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; + case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; + case value_t::array : assigner(array_ , v.array_ ); break; + case value_t::table : assigner(table_ , v.table_ ); break; + default: break; + } + } + basic_value(basic_value&& v) + : type_(v.type()), region_info_(std::move(v.region_info_)), + comments_(std::move(v.comments_)) + { + switch(this->type_) // here this->type_ is already initialized + { + case value_t::boolean : assigner(boolean_ , std::move(v.boolean_ )); break; + case value_t::integer : assigner(integer_ , std::move(v.integer_ )); break; + case value_t::floating : assigner(floating_ , std::move(v.floating_ )); break; + case value_t::string : assigner(string_ , std::move(v.string_ )); break; + case value_t::offset_datetime: assigner(offset_datetime_, std::move(v.offset_datetime_)); break; + case value_t::local_datetime : assigner(local_datetime_ , std::move(v.local_datetime_ )); break; + case value_t::local_date : assigner(local_date_ , std::move(v.local_date_ )); break; + case value_t::local_time : assigner(local_time_ , std::move(v.local_time_ )); break; + case value_t::array : assigner(array_ , std::move(v.array_ )); break; + case value_t::table : assigner(table_ , std::move(v.table_ )); break; + default: break; + } + } + basic_value& operator=(const basic_value& v) + { + if(this == std::addressof(v)) {return *this;} + this->cleanup(); + this->region_info_ = v.region_info_; + this->comments_ = v.comments_; + this->type_ = v.type(); + switch(this->type_) + { + case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; + case value_t::integer : assigner(integer_ , v.integer_ ); break; + case value_t::floating : assigner(floating_ , v.floating_ ); break; + case value_t::string : assigner(string_ , v.string_ ); break; + case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; + case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; + case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; + case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; + case value_t::array : assigner(array_ , v.array_ ); break; + case value_t::table : assigner(table_ , v.table_ ); break; + default: break; + } + return *this; + } + basic_value& operator=(basic_value&& v) + { + if(this == std::addressof(v)) {return *this;} + this->cleanup(); + this->region_info_ = std::move(v.region_info_); + this->comments_ = std::move(v.comments_); + this->type_ = v.type(); + switch(this->type_) + { + case value_t::boolean : assigner(boolean_ , std::move(v.boolean_ )); break; + case value_t::integer : assigner(integer_ , std::move(v.integer_ )); break; + case value_t::floating : assigner(floating_ , std::move(v.floating_ )); break; + case value_t::string : assigner(string_ , std::move(v.string_ )); break; + case value_t::offset_datetime: assigner(offset_datetime_, std::move(v.offset_datetime_)); break; + case value_t::local_datetime : assigner(local_datetime_ , std::move(v.local_datetime_ )); break; + case value_t::local_date : assigner(local_date_ , std::move(v.local_date_ )); break; + case value_t::local_time : assigner(local_time_ , std::move(v.local_time_ )); break; + case value_t::array : assigner(array_ , std::move(v.array_ )); break; + case value_t::table : assigner(table_ , std::move(v.table_ )); break; + default: break; + } + return *this; + } + + // overwrite comments ---------------------------------------------------- + + basic_value(const basic_value& v, std::vector com) + : type_(v.type()), region_info_(v.region_info_), + comments_(std::move(com)) + { + switch(v.type()) + { + case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; + case value_t::integer : assigner(integer_ , v.integer_ ); break; + case value_t::floating : assigner(floating_ , v.floating_ ); break; + case value_t::string : assigner(string_ , v.string_ ); break; + case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; + case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; + case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; + case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; + case value_t::array : assigner(array_ , v.array_ ); break; + case value_t::table : assigner(table_ , v.table_ ); break; + default: break; + } + } + + basic_value(basic_value&& v, std::vector com) + : type_(v.type()), region_info_(std::move(v.region_info_)), + comments_(std::move(com)) + { + switch(this->type_) // here this->type_ is already initialized + { + case value_t::boolean : assigner(boolean_ , std::move(v.boolean_ )); break; + case value_t::integer : assigner(integer_ , std::move(v.integer_ )); break; + case value_t::floating : assigner(floating_ , std::move(v.floating_ )); break; + case value_t::string : assigner(string_ , std::move(v.string_ )); break; + case value_t::offset_datetime: assigner(offset_datetime_, std::move(v.offset_datetime_)); break; + case value_t::local_datetime : assigner(local_datetime_ , std::move(v.local_datetime_ )); break; + case value_t::local_date : assigner(local_date_ , std::move(v.local_date_ )); break; + case value_t::local_time : assigner(local_time_ , std::move(v.local_time_ )); break; + case value_t::array : assigner(array_ , std::move(v.array_ )); break; + case value_t::table : assigner(table_ , std::move(v.table_ )); break; + default: break; + } + } + + // ----------------------------------------------------------------------- + // conversion between different basic_values. + template class T, + template class A> + basic_value(const basic_value& v) + : type_(v.type()), region_info_(v.region_info_), comments_(v.comments()) + { + switch(v.type()) + { + case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; + case value_t::integer : assigner(integer_ , v.integer_ ); break; + case value_t::floating : assigner(floating_ , v.floating_ ); break; + case value_t::string : assigner(string_ , v.string_ ); break; + case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; + case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; + case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; + case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; + case value_t::array : + { + array_type tmp(v.as_array(std::nothrow).begin(), + v.as_array(std::nothrow).end()); + assigner(array_, std::move(tmp)); + break; + } + case value_t::table : + { + table_type tmp(v.as_table(std::nothrow).begin(), + v.as_table(std::nothrow).end()); + assigner(table_, std::move(tmp)); + break; + } + default: break; + } + } + template class T, + template class A> + basic_value(const basic_value& v, std::vector com) + : type_(v.type()), region_info_(v.region_info_), + comments_(std::move(com)) + { + switch(v.type()) + { + case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; + case value_t::integer : assigner(integer_ , v.integer_ ); break; + case value_t::floating : assigner(floating_ , v.floating_ ); break; + case value_t::string : assigner(string_ , v.string_ ); break; + case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; + case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; + case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; + case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; + case value_t::array : + { + array_type tmp(v.as_array(std::nothrow).begin(), + v.as_array(std::nothrow).end()); + assigner(array_, std::move(tmp)); + break; + } + case value_t::table : + { + table_type tmp(v.as_table(std::nothrow).begin(), + v.as_table(std::nothrow).end()); + assigner(table_, std::move(tmp)); + break; + } + default: break; + } + } + template class T, + template class A> + basic_value& operator=(const basic_value& v) + { + this->region_info_ = v.region_info_; + this->comments_ = comment_type(v.comments()); + this->type_ = v.type(); + switch(v.type()) + { + case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; + case value_t::integer : assigner(integer_ , v.integer_ ); break; + case value_t::floating : assigner(floating_ , v.floating_ ); break; + case value_t::string : assigner(string_ , v.string_ ); break; + case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; + case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; + case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; + case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; + case value_t::array : + { + array_type tmp(v.as_array(std::nothrow).begin(), + v.as_array(std::nothrow).end()); + assigner(array_, std::move(tmp)); + break; + } + case value_t::table : + { + table_type tmp(v.as_table(std::nothrow).begin(), + v.as_table(std::nothrow).end()); + assigner(table_, std::move(tmp)); + break; + } + default: break; + } + return *this; + } + + // boolean ============================================================== + + basic_value(boolean b) + : type_(value_t::boolean), + region_info_(std::make_shared(region_base{})) + { + assigner(this->boolean_, b); + } + basic_value& operator=(boolean b) + { + this->cleanup(); + this->type_ = value_t::boolean; + this->region_info_ = std::make_shared(region_base{}); + assigner(this->boolean_, b); + return *this; + } + basic_value(boolean b, std::vector com) + : type_(value_t::boolean), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->boolean_, b); + } + + // integer ============================================================== + + template, detail::negation>>::value, + std::nullptr_t>::type = nullptr> + basic_value(T i) + : type_(value_t::integer), + region_info_(std::make_shared(region_base{})) + { + assigner(this->integer_, static_cast(i)); + } + + template, detail::negation>>::value, + std::nullptr_t>::type = nullptr> + basic_value& operator=(T i) + { + this->cleanup(); + this->type_ = value_t::integer; + this->region_info_ = std::make_shared(region_base{}); + assigner(this->integer_, static_cast(i)); + return *this; + } + + template, detail::negation>>::value, + std::nullptr_t>::type = nullptr> + basic_value(T i, std::vector com) + : type_(value_t::integer), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->integer_, static_cast(i)); + } + + // floating ============================================================= + + template::value, std::nullptr_t>::type = nullptr> + basic_value(T f) + : type_(value_t::floating), + region_info_(std::make_shared(region_base{})) + { + assigner(this->floating_, static_cast(f)); + } + + + template::value, std::nullptr_t>::type = nullptr> + basic_value& operator=(T f) + { + this->cleanup(); + this->type_ = value_t::floating; + this->region_info_ = std::make_shared(region_base{}); + assigner(this->floating_, static_cast(f)); + return *this; + } + + template::value, std::nullptr_t>::type = nullptr> + basic_value(T f, std::vector com) + : type_(value_t::floating), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->floating_, f); + } + + // string =============================================================== + + basic_value(toml::string s) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})) + { + assigner(this->string_, std::move(s)); + } + basic_value& operator=(toml::string s) + { + this->cleanup(); + this->type_ = value_t::string ; + this->region_info_ = std::make_shared(region_base{}); + assigner(this->string_, s); + return *this; + } + basic_value(toml::string s, std::vector com) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->string_, std::move(s)); + } + + basic_value(std::string s) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})) + { + assigner(this->string_, toml::string(std::move(s))); + } + basic_value& operator=(std::string s) + { + this->cleanup(); + this->type_ = value_t::string ; + this->region_info_ = std::make_shared(region_base{}); + assigner(this->string_, toml::string(std::move(s))); + return *this; + } + basic_value(std::string s, string_t kind) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})) + { + assigner(this->string_, toml::string(std::move(s), kind)); + } + basic_value(std::string s, std::vector com) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->string_, toml::string(std::move(s))); + } + basic_value(std::string s, string_t kind, std::vector com) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->string_, toml::string(std::move(s), kind)); + } + + basic_value(const char* s) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})) + { + assigner(this->string_, toml::string(std::string(s))); + } + basic_value& operator=(const char* s) + { + this->cleanup(); + this->type_ = value_t::string ; + this->region_info_ = std::make_shared(region_base{}); + assigner(this->string_, toml::string(std::string(s))); + return *this; + } + basic_value(const char* s, string_t kind) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})) + { + assigner(this->string_, toml::string(std::string(s), kind)); + } + basic_value(const char* s, std::vector com) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->string_, toml::string(std::string(s))); + } + basic_value(const char* s, string_t kind, std::vector com) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->string_, toml::string(std::string(s), kind)); + } + +#if defined(TOML11_USING_STRING_VIEW) && TOML11_USING_STRING_VIEW>0 + basic_value(std::string_view s) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})) + { + assigner(this->string_, toml::string(s)); + } + basic_value& operator=(std::string_view s) + { + this->cleanup(); + this->type_ = value_t::string ; + this->region_info_ = std::make_shared(region_base{}); + assigner(this->string_, toml::string(s)); + return *this; + } + basic_value(std::string_view s, std::vector com) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->string_, toml::string(s)); + } + basic_value(std::string_view s, string_t kind) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})) + { + assigner(this->string_, toml::string(s, kind)); + } + basic_value(std::string_view s, string_t kind, std::vector com) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->string_, toml::string(s, kind)); + } +#endif + + // local date =========================================================== + + basic_value(const local_date& ld) + : type_(value_t::local_date), + region_info_(std::make_shared(region_base{})) + { + assigner(this->local_date_, ld); + } + basic_value& operator=(const local_date& ld) + { + this->cleanup(); + this->type_ = value_t::local_date; + this->region_info_ = std::make_shared(region_base{}); + assigner(this->local_date_, ld); + return *this; + } + basic_value(const local_date& ld, std::vector com) + : type_(value_t::local_date), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->local_date_, ld); + } + + // local time =========================================================== + + basic_value(const local_time& lt) + : type_(value_t::local_time), + region_info_(std::make_shared(region_base{})) + { + assigner(this->local_time_, lt); + } + basic_value(const local_time& lt, std::vector com) + : type_(value_t::local_time), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->local_time_, lt); + } + basic_value& operator=(const local_time& lt) + { + this->cleanup(); + this->type_ = value_t::local_time; + this->region_info_ = std::make_shared(region_base{}); + assigner(this->local_time_, lt); + return *this; + } + + template + basic_value(const std::chrono::duration& dur) + : type_(value_t::local_time), + region_info_(std::make_shared(region_base{})) + { + assigner(this->local_time_, local_time(dur)); + } + template + basic_value(const std::chrono::duration& dur, + std::vector com) + : type_(value_t::local_time), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->local_time_, local_time(dur)); + } + template + basic_value& operator=(const std::chrono::duration& dur) + { + this->cleanup(); + this->type_ = value_t::local_time; + this->region_info_ = std::make_shared(region_base{}); + assigner(this->local_time_, local_time(dur)); + return *this; + } + + // local datetime ======================================================= + + basic_value(const local_datetime& ldt) + : type_(value_t::local_datetime), + region_info_(std::make_shared(region_base{})) + { + assigner(this->local_datetime_, ldt); + } + basic_value(const local_datetime& ldt, std::vector com) + : type_(value_t::local_datetime), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->local_datetime_, ldt); + } + basic_value& operator=(const local_datetime& ldt) + { + this->cleanup(); + this->type_ = value_t::local_datetime; + this->region_info_ = std::make_shared(region_base{}); + assigner(this->local_datetime_, ldt); + return *this; + } + + // offset datetime ====================================================== + + basic_value(const offset_datetime& odt) + : type_(value_t::offset_datetime), + region_info_(std::make_shared(region_base{})) + { + assigner(this->offset_datetime_, odt); + } + basic_value(const offset_datetime& odt, std::vector com) + : type_(value_t::offset_datetime), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->offset_datetime_, odt); + } + basic_value& operator=(const offset_datetime& odt) + { + this->cleanup(); + this->type_ = value_t::offset_datetime; + this->region_info_ = std::make_shared(region_base{}); + assigner(this->offset_datetime_, odt); + return *this; + } + basic_value(const std::chrono::system_clock::time_point& tp) + : type_(value_t::offset_datetime), + region_info_(std::make_shared(region_base{})) + { + assigner(this->offset_datetime_, offset_datetime(tp)); + } + basic_value(const std::chrono::system_clock::time_point& tp, + std::vector com) + : type_(value_t::offset_datetime), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->offset_datetime_, offset_datetime(tp)); + } + basic_value& operator=(const std::chrono::system_clock::time_point& tp) + { + this->cleanup(); + this->type_ = value_t::offset_datetime; + this->region_info_ = std::make_shared(region_base{}); + assigner(this->offset_datetime_, offset_datetime(tp)); + return *this; + } + + // array ================================================================ + + basic_value(const array_type& ary) + : type_(value_t::array), + region_info_(std::make_shared(region_base{})) + { + assigner(this->array_, ary); + } + basic_value(const array_type& ary, std::vector com) + : type_(value_t::array), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->array_, ary); + } + basic_value& operator=(const array_type& ary) + { + this->cleanup(); + this->type_ = value_t::array ; + this->region_info_ = std::make_shared(region_base{}); + assigner(this->array_, ary); + return *this; + } + + // array (initializer_list) ---------------------------------------------- + + template::value, + std::nullptr_t>::type = nullptr> + basic_value(std::initializer_list list) + : type_(value_t::array), + region_info_(std::make_shared(region_base{})) + { + array_type ary(list.begin(), list.end()); + assigner(this->array_, std::move(ary)); + } + template::value, + std::nullptr_t>::type = nullptr> + basic_value(std::initializer_list list, std::vector com) + : type_(value_t::array), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + array_type ary(list.begin(), list.end()); + assigner(this->array_, std::move(ary)); + } + template::value, + std::nullptr_t>::type = nullptr> + basic_value& operator=(std::initializer_list list) + { + this->cleanup(); + this->type_ = value_t::array; + this->region_info_ = std::make_shared(region_base{}); + + array_type ary(list.begin(), list.end()); + assigner(this->array_, std::move(ary)); + return *this; + } + + // array (STL Containers) ------------------------------------------------ + + template>, + detail::is_container + >::value, std::nullptr_t>::type = nullptr> + basic_value(const T& list) + : type_(value_t::array), + region_info_(std::make_shared(region_base{})) + { + static_assert(std::is_convertible::value, + "elements of a container should be convertible to toml::value"); + + array_type ary(list.size()); + std::copy(list.begin(), list.end(), ary.begin()); + assigner(this->array_, std::move(ary)); + } + template>, + detail::is_container + >::value, std::nullptr_t>::type = nullptr> + basic_value(const T& list, std::vector com) + : type_(value_t::array), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + static_assert(std::is_convertible::value, + "elements of a container should be convertible to toml::value"); + + array_type ary(list.size()); + std::copy(list.begin(), list.end(), ary.begin()); + assigner(this->array_, std::move(ary)); + } + template>, + detail::is_container + >::value, std::nullptr_t>::type = nullptr> + basic_value& operator=(const T& list) + { + static_assert(std::is_convertible::value, + "elements of a container should be convertible to toml::value"); + + this->cleanup(); + this->type_ = value_t::array; + this->region_info_ = std::make_shared(region_base{}); + + array_type ary(list.size()); + std::copy(list.begin(), list.end(), ary.begin()); + assigner(this->array_, std::move(ary)); + return *this; + } + + // table ================================================================ + + basic_value(const table_type& tab) + : type_(value_t::table), + region_info_(std::make_shared(region_base{})) + { + assigner(this->table_, tab); + } + basic_value(const table_type& tab, std::vector com) + : type_(value_t::table), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + assigner(this->table_, tab); + } + basic_value& operator=(const table_type& tab) + { + this->cleanup(); + this->type_ = value_t::table; + this->region_info_ = std::make_shared(region_base{}); + assigner(this->table_, tab); + return *this; + } + + // initializer-list ------------------------------------------------------ + + basic_value(std::initializer_list> list) + : type_(value_t::table), + region_info_(std::make_shared(region_base{})) + { + table_type tab; + for(const auto& elem : list) {tab[elem.first] = elem.second;} + assigner(this->table_, std::move(tab)); + } + + basic_value(std::initializer_list> list, + std::vector com) + : type_(value_t::table), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + table_type tab; + for(const auto& elem : list) {tab[elem.first] = elem.second;} + assigner(this->table_, std::move(tab)); + } + basic_value& operator=(std::initializer_list> list) + { + this->cleanup(); + this->type_ = value_t::table; + this->region_info_ = std::make_shared(region_base{}); + + table_type tab; + for(const auto& elem : list) {tab[elem.first] = elem.second;} + assigner(this->table_, std::move(tab)); + return *this; + } + + // other table-like ----------------------------------------------------- + + template>, + detail::is_map + >::value, std::nullptr_t>::type = nullptr> + basic_value(const Map& mp) + : type_(value_t::table), + region_info_(std::make_shared(region_base{})) + { + table_type tab; + for(const auto& elem : mp) {tab[elem.first] = elem.second;} + assigner(this->table_, std::move(tab)); + } + template>, + detail::is_map + >::value, std::nullptr_t>::type = nullptr> + basic_value(const Map& mp, std::vector com) + : type_(value_t::table), + region_info_(std::make_shared(region_base{})), + comments_(std::move(com)) + { + table_type tab; + for(const auto& elem : mp) {tab[elem.first] = elem.second;} + assigner(this->table_, std::move(tab)); + } + template>, + detail::is_map + >::value, std::nullptr_t>::type = nullptr> + basic_value& operator=(const Map& mp) + { + this->cleanup(); + this->type_ = value_t::table; + this->region_info_ = std::make_shared(region_base{}); + + table_type tab; + for(const auto& elem : mp) {tab[elem.first] = elem.second;} + assigner(this->table_, std::move(tab)); + return *this; + } + + // user-defined ========================================================= + + // convert using into_toml() method ------------------------------------- + + template::value, std::nullptr_t>::type = nullptr> + basic_value(const T& ud): basic_value(ud.into_toml()) {} + + template::value, std::nullptr_t>::type = nullptr> + basic_value(const T& ud, std::vector com) + : basic_value(ud.into_toml(), std::move(com)) + {} + template::value, std::nullptr_t>::type = nullptr> + basic_value& operator=(const T& ud) + { + *this = ud.into_toml(); + return *this; + } + + // convert using into struct ----------------------------------------- + + template)> + basic_value(const T& ud): basic_value(::toml::into::into_toml(ud)) {} + template)> + basic_value(const T& ud, std::vector com) + : basic_value(::toml::into::into_toml(ud), std::move(com)) + {} + template)> + basic_value& operator=(const T& ud) + { + *this = ::toml::into::into_toml(ud); + return *this; + } + + // for internal use ------------------------------------------------------ + // + // Those constructors take detail::region that contains parse result. + + basic_value(boolean b, detail::region reg, std::vector cm) + : type_(value_t::boolean), + region_info_(std::make_shared(std::move(reg))), + comments_(std::move(cm)) + { + assigner(this->boolean_, b); + } + template, detail::negation> + >::value, std::nullptr_t>::type = nullptr> + basic_value(T i, detail::region reg, std::vector cm) + : type_(value_t::integer), + region_info_(std::make_shared(std::move(reg))), + comments_(std::move(cm)) + { + assigner(this->integer_, static_cast(i)); + } + template::value, std::nullptr_t>::type = nullptr> + basic_value(T f, detail::region reg, std::vector cm) + : type_(value_t::floating), + region_info_(std::make_shared(std::move(reg))), + comments_(std::move(cm)) + { + assigner(this->floating_, static_cast(f)); + } + basic_value(toml::string s, detail::region reg, + std::vector cm) + : type_(value_t::string), + region_info_(std::make_shared(std::move(reg))), + comments_(std::move(cm)) + { + assigner(this->string_, std::move(s)); + } + basic_value(const local_date& ld, detail::region reg, + std::vector cm) + : type_(value_t::local_date), + region_info_(std::make_shared(std::move(reg))), + comments_(std::move(cm)) + { + assigner(this->local_date_, ld); + } + basic_value(const local_time& lt, detail::region reg, + std::vector cm) + : type_(value_t::local_time), + region_info_(std::make_shared(std::move(reg))), + comments_(std::move(cm)) + { + assigner(this->local_time_, lt); + } + basic_value(const local_datetime& ldt, detail::region reg, + std::vector cm) + : type_(value_t::local_datetime), + region_info_(std::make_shared(std::move(reg))), + comments_(std::move(cm)) + { + assigner(this->local_datetime_, ldt); + } + basic_value(const offset_datetime& odt, detail::region reg, + std::vector cm) + : type_(value_t::offset_datetime), + region_info_(std::make_shared(std::move(reg))), + comments_(std::move(cm)) + { + assigner(this->offset_datetime_, odt); + } + basic_value(const array_type& ary, detail::region reg, + std::vector cm) + : type_(value_t::array), + region_info_(std::make_shared(std::move(reg))), + comments_(std::move(cm)) + { + assigner(this->array_, ary); + } + basic_value(const table_type& tab, detail::region reg, + std::vector cm) + : type_(value_t::table), + region_info_(std::make_shared(std::move(reg))), + comments_(std::move(cm)) + { + assigner(this->table_, tab); + } + + template::value, + std::nullptr_t>::type = nullptr> + basic_value(std::pair parse_result, std::vector com) + : basic_value(std::move(parse_result.first), + std::move(parse_result.second), + std::move(com)) + {} + + // type checking and casting ============================================ + + template::value, + std::nullptr_t>::type = nullptr> + bool is() const noexcept + { + return detail::type_to_enum::value == this->type_; + } + bool is(value_t t) const noexcept {return t == this->type_;} + + bool is_uninitialized() const noexcept {return this->is(value_t::empty );} + bool is_boolean() const noexcept {return this->is(value_t::boolean );} + bool is_integer() const noexcept {return this->is(value_t::integer );} + bool is_floating() const noexcept {return this->is(value_t::floating );} + bool is_string() const noexcept {return this->is(value_t::string );} + bool is_offset_datetime() const noexcept {return this->is(value_t::offset_datetime);} + bool is_local_datetime() const noexcept {return this->is(value_t::local_datetime );} + bool is_local_date() const noexcept {return this->is(value_t::local_date );} + bool is_local_time() const noexcept {return this->is(value_t::local_time );} + bool is_array() const noexcept {return this->is(value_t::array );} + bool is_table() const noexcept {return this->is(value_t::table );} + + value_t type() const noexcept {return type_;} + + template + typename detail::enum_to_type::type& cast() & + { + if(this->type_ != T) + { + detail::throw_bad_cast("toml::value::cast: ", this->type_, *this); + } + return detail::switch_cast::invoke(*this); + } + template + typename detail::enum_to_type::type const& cast() const& + { + if(this->type_ != T) + { + detail::throw_bad_cast("toml::value::cast: ", this->type_, *this); + } + return detail::switch_cast::invoke(*this); + } + template + typename detail::enum_to_type::type&& cast() && + { + if(this->type_ != T) + { + detail::throw_bad_cast("toml::value::cast: ", this->type_, *this); + } + return detail::switch_cast::invoke(std::move(*this)); + } + + // ------------------------------------------------------------------------ + // nothrow version + + boolean const& as_boolean (const std::nothrow_t&) const& noexcept {return this->boolean_;} + integer const& as_integer (const std::nothrow_t&) const& noexcept {return this->integer_;} + floating const& as_floating (const std::nothrow_t&) const& noexcept {return this->floating_;} + string const& as_string (const std::nothrow_t&) const& noexcept {return this->string_;} + offset_datetime const& as_offset_datetime(const std::nothrow_t&) const& noexcept {return this->offset_datetime_;} + local_datetime const& as_local_datetime (const std::nothrow_t&) const& noexcept {return this->local_datetime_;} + local_date const& as_local_date (const std::nothrow_t&) const& noexcept {return this->local_date_;} + local_time const& as_local_time (const std::nothrow_t&) const& noexcept {return this->local_time_;} + array_type const& as_array (const std::nothrow_t&) const& noexcept {return this->array_.value();} + table_type const& as_table (const std::nothrow_t&) const& noexcept {return this->table_.value();} + + boolean & as_boolean (const std::nothrow_t&) & noexcept {return this->boolean_;} + integer & as_integer (const std::nothrow_t&) & noexcept {return this->integer_;} + floating & as_floating (const std::nothrow_t&) & noexcept {return this->floating_;} + string & as_string (const std::nothrow_t&) & noexcept {return this->string_;} + offset_datetime& as_offset_datetime(const std::nothrow_t&) & noexcept {return this->offset_datetime_;} + local_datetime & as_local_datetime (const std::nothrow_t&) & noexcept {return this->local_datetime_;} + local_date & as_local_date (const std::nothrow_t&) & noexcept {return this->local_date_;} + local_time & as_local_time (const std::nothrow_t&) & noexcept {return this->local_time_;} + array_type & as_array (const std::nothrow_t&) & noexcept {return this->array_.value();} + table_type & as_table (const std::nothrow_t&) & noexcept {return this->table_.value();} + + boolean && as_boolean (const std::nothrow_t&) && noexcept {return std::move(this->boolean_);} + integer && as_integer (const std::nothrow_t&) && noexcept {return std::move(this->integer_);} + floating && as_floating (const std::nothrow_t&) && noexcept {return std::move(this->floating_);} + string && as_string (const std::nothrow_t&) && noexcept {return std::move(this->string_);} + offset_datetime&& as_offset_datetime(const std::nothrow_t&) && noexcept {return std::move(this->offset_datetime_);} + local_datetime && as_local_datetime (const std::nothrow_t&) && noexcept {return std::move(this->local_datetime_);} + local_date && as_local_date (const std::nothrow_t&) && noexcept {return std::move(this->local_date_);} + local_time && as_local_time (const std::nothrow_t&) && noexcept {return std::move(this->local_time_);} + array_type && as_array (const std::nothrow_t&) && noexcept {return std::move(this->array_.value());} + table_type && as_table (const std::nothrow_t&) && noexcept {return std::move(this->table_.value());} + + // ======================================================================== + // throw version + // ------------------------------------------------------------------------ + // const reference {{{ + + boolean const& as_boolean() const& + { + if(this->type_ != value_t::boolean) + { + detail::throw_bad_cast( + "toml::value::as_boolean(): ", this->type_, *this); + } + return this->boolean_; + } + integer const& as_integer() const& + { + if(this->type_ != value_t::integer) + { + detail::throw_bad_cast( + "toml::value::as_integer(): ", this->type_, *this); + } + return this->integer_; + } + floating const& as_floating() const& + { + if(this->type_ != value_t::floating) + { + detail::throw_bad_cast( + "toml::value::as_floating(): ", this->type_, *this); + } + return this->floating_; + } + string const& as_string() const& + { + if(this->type_ != value_t::string) + { + detail::throw_bad_cast( + "toml::value::as_string(): ", this->type_, *this); + } + return this->string_; + } + offset_datetime const& as_offset_datetime() const& + { + if(this->type_ != value_t::offset_datetime) + { + detail::throw_bad_cast( + "toml::value::as_offset_datetime(): ", this->type_, *this); + } + return this->offset_datetime_; + } + local_datetime const& as_local_datetime() const& + { + if(this->type_ != value_t::local_datetime) + { + detail::throw_bad_cast( + "toml::value::as_local_datetime(): ", this->type_, *this); + } + return this->local_datetime_; + } + local_date const& as_local_date() const& + { + if(this->type_ != value_t::local_date) + { + detail::throw_bad_cast( + "toml::value::as_local_date(): ", this->type_, *this); + } + return this->local_date_; + } + local_time const& as_local_time() const& + { + if(this->type_ != value_t::local_time) + { + detail::throw_bad_cast( + "toml::value::as_local_time(): ", this->type_, *this); + } + return this->local_time_; + } + array_type const& as_array() const& + { + if(this->type_ != value_t::array) + { + detail::throw_bad_cast( + "toml::value::as_array(): ", this->type_, *this); + } + return this->array_.value(); + } + table_type const& as_table() const& + { + if(this->type_ != value_t::table) + { + detail::throw_bad_cast( + "toml::value::as_table(): ", this->type_, *this); + } + return this->table_.value(); + } + // }}} + // ------------------------------------------------------------------------ + // nonconst reference {{{ + + boolean & as_boolean() & + { + if(this->type_ != value_t::boolean) + { + detail::throw_bad_cast( + "toml::value::as_boolean(): ", this->type_, *this); + } + return this->boolean_; + } + integer & as_integer() & + { + if(this->type_ != value_t::integer) + { + detail::throw_bad_cast( + "toml::value::as_integer(): ", this->type_, *this); + } + return this->integer_; + } + floating & as_floating() & + { + if(this->type_ != value_t::floating) + { + detail::throw_bad_cast( + "toml::value::as_floating(): ", this->type_, *this); + } + return this->floating_; + } + string & as_string() & + { + if(this->type_ != value_t::string) + { + detail::throw_bad_cast( + "toml::value::as_string(): ", this->type_, *this); + } + return this->string_; + } + offset_datetime & as_offset_datetime() & + { + if(this->type_ != value_t::offset_datetime) + { + detail::throw_bad_cast( + "toml::value::as_offset_datetime(): ", this->type_, *this); + } + return this->offset_datetime_; + } + local_datetime & as_local_datetime() & + { + if(this->type_ != value_t::local_datetime) + { + detail::throw_bad_cast( + "toml::value::as_local_datetime(): ", this->type_, *this); + } + return this->local_datetime_; + } + local_date & as_local_date() & + { + if(this->type_ != value_t::local_date) + { + detail::throw_bad_cast( + "toml::value::as_local_date(): ", this->type_, *this); + } + return this->local_date_; + } + local_time & as_local_time() & + { + if(this->type_ != value_t::local_time) + { + detail::throw_bad_cast( + "toml::value::as_local_time(): ", this->type_, *this); + } + return this->local_time_; + } + array_type & as_array() & + { + if(this->type_ != value_t::array) + { + detail::throw_bad_cast( + "toml::value::as_array(): ", this->type_, *this); + } + return this->array_.value(); + } + table_type & as_table() & + { + if(this->type_ != value_t::table) + { + detail::throw_bad_cast( + "toml::value::as_table(): ", this->type_, *this); + } + return this->table_.value(); + } + + // }}} + // ------------------------------------------------------------------------ + // rvalue reference {{{ + + boolean && as_boolean() && + { + if(this->type_ != value_t::boolean) + { + detail::throw_bad_cast( + "toml::value::as_boolean(): ", this->type_, *this); + } + return std::move(this->boolean_); + } + integer && as_integer() && + { + if(this->type_ != value_t::integer) + { + detail::throw_bad_cast( + "toml::value::as_integer(): ", this->type_, *this); + } + return std::move(this->integer_); + } + floating && as_floating() && + { + if(this->type_ != value_t::floating) + { + detail::throw_bad_cast( + "toml::value::as_floating(): ", this->type_, *this); + } + return std::move(this->floating_); + } + string && as_string() && + { + if(this->type_ != value_t::string) + { + detail::throw_bad_cast( + "toml::value::as_string(): ", this->type_, *this); + } + return std::move(this->string_); + } + offset_datetime && as_offset_datetime() && + { + if(this->type_ != value_t::offset_datetime) + { + detail::throw_bad_cast( + "toml::value::as_offset_datetime(): ", this->type_, *this); + } + return std::move(this->offset_datetime_); + } + local_datetime && as_local_datetime() && + { + if(this->type_ != value_t::local_datetime) + { + detail::throw_bad_cast( + "toml::value::as_local_datetime(): ", this->type_, *this); + } + return std::move(this->local_datetime_); + } + local_date && as_local_date() && + { + if(this->type_ != value_t::local_date) + { + detail::throw_bad_cast( + "toml::value::as_local_date(): ", this->type_, *this); + } + return std::move(this->local_date_); + } + local_time && as_local_time() && + { + if(this->type_ != value_t::local_time) + { + detail::throw_bad_cast( + "toml::value::as_local_time(): ", this->type_, *this); + } + return std::move(this->local_time_); + } + array_type && as_array() && + { + if(this->type_ != value_t::array) + { + detail::throw_bad_cast( + "toml::value::as_array(): ", this->type_, *this); + } + return std::move(this->array_.value()); + } + table_type && as_table() && + { + if(this->type_ != value_t::table) + { + detail::throw_bad_cast( + "toml::value::as_table(): ", this->type_, *this); + } + return std::move(this->table_.value()); + } + // }}} + + // accessors ============================================================= + // + // may throw type_error or out_of_range + // + value_type& at(const key& k) + { + if(!this->is_table()) + { + detail::throw_bad_cast( + "toml::value::at(key): ", this->type_, *this); + } + if(this->as_table(std::nothrow).count(k) == 0) + { + detail::throw_key_not_found_error(*this, k); + } + return this->as_table(std::nothrow).at(k); + } + value_type const& at(const key& k) const + { + if(!this->is_table()) + { + detail::throw_bad_cast( + "toml::value::at(key): ", this->type_, *this); + } + if(this->as_table(std::nothrow).count(k) == 0) + { + detail::throw_key_not_found_error(*this, k); + } + return this->as_table(std::nothrow).at(k); + } + value_type& operator[](const key& k) + { + if(this->is_uninitialized()) + { + *this = table_type{}; + } + else if(!this->is_table()) // initialized, but not a table + { + detail::throw_bad_cast( + "toml::value::operator[](key): ", this->type_, *this); + } + return this->as_table(std::nothrow)[k]; + } + + value_type& at(const std::size_t idx) + { + if(!this->is_array()) + { + detail::throw_bad_cast( + "toml::value::at(idx): ", this->type_, *this); + } + if(this->as_array(std::nothrow).size() <= idx) + { + throw std::out_of_range(detail::format_underline( + "toml::value::at(idx): no element corresponding to the index", { + {this->location(), concat_to_string("the length is ", + this->as_array(std::nothrow).size(), + ", and the specified index is ", idx)} + })); + } + return this->as_array().at(idx); + } + value_type const& at(const std::size_t idx) const + { + if(!this->is_array()) + { + detail::throw_bad_cast( + "toml::value::at(idx): ", this->type_, *this); + } + if(this->as_array(std::nothrow).size() <= idx) + { + throw std::out_of_range(detail::format_underline( + "toml::value::at(idx): no element corresponding to the index", { + {this->location(), concat_to_string("the length is ", + this->as_array(std::nothrow).size(), + ", and the specified index is ", idx)} + })); + } + return this->as_array(std::nothrow).at(idx); + } + + value_type& operator[](const std::size_t idx) noexcept + { + // no check... + return this->as_array(std::nothrow)[idx]; + } + value_type const& operator[](const std::size_t idx) const noexcept + { + // no check... + return this->as_array(std::nothrow)[idx]; + } + + void push_back(const value_type& x) + { + if(!this->is_array()) + { + detail::throw_bad_cast( + "toml::value::push_back(value): ", this->type_, *this); + } + this->as_array(std::nothrow).push_back(x); + return; + } + void push_back(value_type&& x) + { + if(!this->is_array()) + { + detail::throw_bad_cast( + "toml::value::push_back(value): ", this->type_, *this); + } + this->as_array(std::nothrow).push_back(std::move(x)); + return; + } + + template + value_type& emplace_back(Ts&& ... args) + { + if(!this->is_array()) + { + detail::throw_bad_cast( + "toml::value::emplace_back(...): ", this->type_, *this); + } + this->as_array(std::nothrow).emplace_back(std::forward(args) ...); + return this->as_array(std::nothrow).back(); + } + + std::size_t size() const + { + switch(this->type_) + { + case value_t::array: + { + return this->as_array(std::nothrow).size(); + } + case value_t::table: + { + return this->as_table(std::nothrow).size(); + } + case value_t::string: + { + return this->as_string(std::nothrow).str.size(); + } + default: + { + throw type_error(detail::format_underline( + "toml::value::size(): bad_cast to container types", { + {this->location(), + concat_to_string("the actual type is ", this->type_)} + }), this->location()); + } + } + } + + std::size_t count(const key_type& k) const + { + if(!this->is_table()) + { + detail::throw_bad_cast( + "toml::value::count(key): ", this->type_, *this); + } + return this->as_table(std::nothrow).count(k); + } + + bool contains(const key_type& k) const + { + if(!this->is_table()) + { + detail::throw_bad_cast( + "toml::value::contains(key): ", this->type_, *this); + } + return (this->as_table(std::nothrow).count(k) != 0); + } + + source_location location() const + { + return source_location(this->region_info_.get()); + } + + comment_type const& comments() const noexcept {return this->comments_;} + comment_type& comments() noexcept {return this->comments_;} + + private: + + void cleanup() noexcept + { + switch(this->type_) + { + case value_t::string : {string_.~string(); return;} + case value_t::array : {array_.~array_storage(); return;} + case value_t::table : {table_.~table_storage(); return;} + default : return; + } + } + + // for error messages + template + friend region_base const* detail::get_region(const Value& v); + + template + friend void detail::change_region(Value& v, detail::region reg); + + private: + + using array_storage = detail::storage; + using table_storage = detail::storage; + + value_t type_; + union + { + boolean boolean_; + integer integer_; + floating floating_; + string string_; + offset_datetime offset_datetime_; + local_datetime local_datetime_; + local_date local_date_; + local_time local_time_; + array_storage array_; + table_storage table_; + }; + std::shared_ptr region_info_; + comment_type comments_; +}; + +// default toml::value and default array/table. +// TOML11_DEFAULT_COMMENT_STRATEGY is defined in comments.hpp +using value = basic_value; +using array = typename value::array_type; +using table = typename value::table_type; + +template class T, template class A> +inline bool +operator==(const basic_value& lhs, const basic_value& rhs) +{ + if(lhs.type() != rhs.type()) {return false;} + if(lhs.comments() != rhs.comments()) {return false;} + + switch(lhs.type()) + { + case value_t::boolean : + { + return lhs.as_boolean() == rhs.as_boolean(); + } + case value_t::integer : + { + return lhs.as_integer() == rhs.as_integer(); + } + case value_t::floating : + { + return lhs.as_floating() == rhs.as_floating(); + } + case value_t::string : + { + return lhs.as_string() == rhs.as_string(); + } + case value_t::offset_datetime: + { + return lhs.as_offset_datetime() == rhs.as_offset_datetime(); + } + case value_t::local_datetime: + { + return lhs.as_local_datetime() == rhs.as_local_datetime(); + } + case value_t::local_date: + { + return lhs.as_local_date() == rhs.as_local_date(); + } + case value_t::local_time: + { + return lhs.as_local_time() == rhs.as_local_time(); + } + case value_t::array : + { + return lhs.as_array() == rhs.as_array(); + } + case value_t::table : + { + return lhs.as_table() == rhs.as_table(); + } + case value_t::empty : {return true; } + default: {return false;} + } +} + +template class T, template class A> +inline bool operator!=(const basic_value& lhs, const basic_value& rhs) +{ + return !(lhs == rhs); +} + +template class T, template class A> +typename std::enable_if::array_type>, + detail::is_comparable::table_type> + >::value, bool>::type +operator<(const basic_value& lhs, const basic_value& rhs) +{ + if(lhs.type() != rhs.type()){return (lhs.type() < rhs.type());} + switch(lhs.type()) + { + case value_t::boolean : + { + return lhs.as_boolean() < rhs.as_boolean() || + (lhs.as_boolean() == rhs.as_boolean() && + lhs.comments() < rhs.comments()); + } + case value_t::integer : + { + return lhs.as_integer() < rhs.as_integer() || + (lhs.as_integer() == rhs.as_integer() && + lhs.comments() < rhs.comments()); + } + case value_t::floating : + { + return lhs.as_floating() < rhs.as_floating() || + (lhs.as_floating() == rhs.as_floating() && + lhs.comments() < rhs.comments()); + } + case value_t::string : + { + return lhs.as_string() < rhs.as_string() || + (lhs.as_string() == rhs.as_string() && + lhs.comments() < rhs.comments()); + } + case value_t::offset_datetime: + { + return lhs.as_offset_datetime() < rhs.as_offset_datetime() || + (lhs.as_offset_datetime() == rhs.as_offset_datetime() && + lhs.comments() < rhs.comments()); + } + case value_t::local_datetime: + { + return lhs.as_local_datetime() < rhs.as_local_datetime() || + (lhs.as_local_datetime() == rhs.as_local_datetime() && + lhs.comments() < rhs.comments()); + } + case value_t::local_date: + { + return lhs.as_local_date() < rhs.as_local_date() || + (lhs.as_local_date() == rhs.as_local_date() && + lhs.comments() < rhs.comments()); + } + case value_t::local_time: + { + return lhs.as_local_time() < rhs.as_local_time() || + (lhs.as_local_time() == rhs.as_local_time() && + lhs.comments() < rhs.comments()); + } + case value_t::array : + { + return lhs.as_array() < rhs.as_array() || + (lhs.as_array() == rhs.as_array() && + lhs.comments() < rhs.comments()); + } + case value_t::table : + { + return lhs.as_table() < rhs.as_table() || + (lhs.as_table() == rhs.as_table() && + lhs.comments() < rhs.comments()); + } + case value_t::empty : + { + return lhs.comments() < rhs.comments(); + } + default: + { + return lhs.comments() < rhs.comments(); + } + } +} + +template class T, template class A> +typename std::enable_if::array_type>, + detail::is_comparable::table_type> + >::value, bool>::type +operator<=(const basic_value& lhs, const basic_value& rhs) +{ + return (lhs < rhs) || (lhs == rhs); +} +template class T, template class A> +typename std::enable_if::array_type>, + detail::is_comparable::table_type> + >::value, bool>::type +operator>(const basic_value& lhs, const basic_value& rhs) +{ + return !(lhs <= rhs); +} +template class T, template class A> +typename std::enable_if::array_type>, + detail::is_comparable::table_type> + >::value, bool>::type +operator>=(const basic_value& lhs, const basic_value& rhs) +{ + return !(lhs < rhs); +} + +template class T, template class A> +inline std::string format_error(const std::string& err_msg, + const basic_value& v, const std::string& comment, + std::vector hints = {}, + const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED) +{ + return detail::format_underline(err_msg, {{v.location(), comment}}, + std::move(hints), colorize); +} + +template class T, template class A> +inline std::string format_error(const std::string& err_msg, + const toml::basic_value& v1, const std::string& comment1, + const toml::basic_value& v2, const std::string& comment2, + std::vector hints = {}, + const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED) +{ + return detail::format_underline(err_msg, { + {v1.location(), comment1}, {v2.location(), comment2} + }, std::move(hints), colorize); +} + +template class T, template class A> +inline std::string format_error(const std::string& err_msg, + const toml::basic_value& v1, const std::string& comment1, + const toml::basic_value& v2, const std::string& comment2, + const toml::basic_value& v3, const std::string& comment3, + std::vector hints = {}, + const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED) +{ + return detail::format_underline(err_msg, {{v1.location(), comment1}, + {v2.location(), comment2}, {v3.location(), comment3} + }, std::move(hints), colorize); +} + +template class T, template class A> +detail::return_type_of_t +visit(Visitor&& visitor, const toml::basic_value& v) +{ + switch(v.type()) + { + case value_t::boolean : {return visitor(v.as_boolean ());} + case value_t::integer : {return visitor(v.as_integer ());} + case value_t::floating : {return visitor(v.as_floating ());} + case value_t::string : {return visitor(v.as_string ());} + case value_t::offset_datetime: {return visitor(v.as_offset_datetime());} + case value_t::local_datetime : {return visitor(v.as_local_datetime ());} + case value_t::local_date : {return visitor(v.as_local_date ());} + case value_t::local_time : {return visitor(v.as_local_time ());} + case value_t::array : {return visitor(v.as_array ());} + case value_t::table : {return visitor(v.as_table ());} + case value_t::empty : break; + default: break; + } + throw std::runtime_error(format_error("[error] toml::visit: toml::basic_value " + "does not have any valid basic_value.", v, "here")); +} + +template class T, template class A> +detail::return_type_of_t +visit(Visitor&& visitor, toml::basic_value& v) +{ + switch(v.type()) + { + case value_t::boolean : {return visitor(v.as_boolean ());} + case value_t::integer : {return visitor(v.as_integer ());} + case value_t::floating : {return visitor(v.as_floating ());} + case value_t::string : {return visitor(v.as_string ());} + case value_t::offset_datetime: {return visitor(v.as_offset_datetime());} + case value_t::local_datetime : {return visitor(v.as_local_datetime ());} + case value_t::local_date : {return visitor(v.as_local_date ());} + case value_t::local_time : {return visitor(v.as_local_time ());} + case value_t::array : {return visitor(v.as_array ());} + case value_t::table : {return visitor(v.as_table ());} + case value_t::empty : break; + default: break; + } + throw std::runtime_error(format_error("[error] toml::visit: toml::basic_value " + "does not have any valid basic_value.", v, "here")); +} + +template class T, template class A> +detail::return_type_of_t +visit(Visitor&& visitor, toml::basic_value&& v) +{ + switch(v.type()) + { + case value_t::boolean : {return visitor(std::move(v.as_boolean ()));} + case value_t::integer : {return visitor(std::move(v.as_integer ()));} + case value_t::floating : {return visitor(std::move(v.as_floating ()));} + case value_t::string : {return visitor(std::move(v.as_string ()));} + case value_t::offset_datetime: {return visitor(std::move(v.as_offset_datetime()));} + case value_t::local_datetime : {return visitor(std::move(v.as_local_datetime ()));} + case value_t::local_date : {return visitor(std::move(v.as_local_date ()));} + case value_t::local_time : {return visitor(std::move(v.as_local_time ()));} + case value_t::array : {return visitor(std::move(v.as_array ()));} + case value_t::table : {return visitor(std::move(v.as_table ()));} + case value_t::empty : break; + default: break; + } + throw std::runtime_error(format_error("[error] toml::visit: toml::basic_value " + "does not have any valid basic_value.", v, "here")); +} + +}// toml +#endif// TOML11_VALUE diff --git a/external/toml11/toml/version.hpp b/external/toml11/toml/version.hpp new file mode 100644 index 0000000..9cbfa39 --- /dev/null +++ b/external/toml11/toml/version.hpp @@ -0,0 +1,42 @@ +#ifndef TOML11_VERSION_HPP +#define TOML11_VERSION_HPP + +// This file checks C++ version. + +#ifndef __cplusplus +# error "__cplusplus is not defined" +#endif + +// Since MSVC does not define `__cplusplus` correctly unless you pass +// `/Zc:__cplusplus` when compiling, the workaround macros are added. +// Those enables you to define version manually or to use MSVC specific +// version macro automatically. +// +// The value of `__cplusplus` macro is defined in the C++ standard spec, but +// MSVC ignores the value, maybe because of backward compatibility. Instead, +// MSVC defines _MSVC_LANG that has the same value as __cplusplus defined in +// the C++ standard. First we check the manual version definition, and then +// we check if _MSVC_LANG is defined. If neither, use normal `__cplusplus`. +// +// FYI: https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=msvc-170 +// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-170 +// +#if defined(TOML11_ENFORCE_CXX11) +# define TOML11_CPLUSPLUS_STANDARD_VERSION 201103L +#elif defined(TOML11_ENFORCE_CXX14) +# define TOML11_CPLUSPLUS_STANDARD_VERSION 201402L +#elif defined(TOML11_ENFORCE_CXX17) +# define TOML11_CPLUSPLUS_STANDARD_VERSION 201703L +#elif defined(TOML11_ENFORCE_CXX20) +# define TOML11_CPLUSPLUS_STANDARD_VERSION 202002L +#elif defined(_MSVC_LANG) && defined(_MSC_VER) && 1910 <= _MSC_VER +# define TOML11_CPLUSPLUS_STANDARD_VERSION _MSVC_LANG +#else +# define TOML11_CPLUSPLUS_STANDARD_VERSION __cplusplus +#endif + +#if TOML11_CPLUSPLUS_STANDARD_VERSION < 201103L && _MSC_VER < 1900 +# error "toml11 requires C++11 or later." +#endif + +#endif// TOML11_VERSION_HPP diff --git a/external/vk_video/vulkan_video_codec_av1std.h b/external/vk_video/vulkan_video_codec_av1std.h new file mode 100644 index 0000000..8ce283e --- /dev/null +++ b/external/vk_video/vulkan_video_codec_av1std.h @@ -0,0 +1,392 @@ +#ifndef VULKAN_VIDEO_CODEC_AV1STD_H_ +#define VULKAN_VIDEO_CODEC_AV1STD_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// vulkan_video_codec_av1std is a preprocessor guard. Do not pass it to API calls. +#define vulkan_video_codec_av1std 1 +#include "vulkan_video_codecs_common.h" +#define STD_VIDEO_AV1_NUM_REF_FRAMES 8 +#define STD_VIDEO_AV1_REFS_PER_FRAME 7 +#define STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME 8 +#define STD_VIDEO_AV1_MAX_TILE_COLS 64 +#define STD_VIDEO_AV1_MAX_TILE_ROWS 64 +#define STD_VIDEO_AV1_MAX_SEGMENTS 8 +#define STD_VIDEO_AV1_SEG_LVL_MAX 8 +#define STD_VIDEO_AV1_PRIMARY_REF_NONE 7 +#define STD_VIDEO_AV1_SELECT_INTEGER_MV 2 +#define STD_VIDEO_AV1_SELECT_SCREEN_CONTENT_TOOLS 2 +#define STD_VIDEO_AV1_SKIP_MODE_FRAMES 2 +#define STD_VIDEO_AV1_MAX_LOOP_FILTER_STRENGTHS 4 +#define STD_VIDEO_AV1_LOOP_FILTER_ADJUSTMENTS 2 +#define STD_VIDEO_AV1_MAX_CDEF_FILTER_STRENGTHS 8 +#define STD_VIDEO_AV1_MAX_NUM_PLANES 3 +#define STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS 6 +#define STD_VIDEO_AV1_MAX_NUM_Y_POINTS 14 +#define STD_VIDEO_AV1_MAX_NUM_CB_POINTS 10 +#define STD_VIDEO_AV1_MAX_NUM_CR_POINTS 10 +#define STD_VIDEO_AV1_MAX_NUM_POS_LUMA 24 +#define STD_VIDEO_AV1_MAX_NUM_POS_CHROMA 25 + +typedef enum StdVideoAV1Profile { + STD_VIDEO_AV1_PROFILE_MAIN = 0, + STD_VIDEO_AV1_PROFILE_HIGH = 1, + STD_VIDEO_AV1_PROFILE_PROFESSIONAL = 2, + STD_VIDEO_AV1_PROFILE_INVALID = 0x7FFFFFFF, + STD_VIDEO_AV1_PROFILE_MAX_ENUM = 0x7FFFFFFF +} StdVideoAV1Profile; + +typedef enum StdVideoAV1Level { + STD_VIDEO_AV1_LEVEL_2_0 = 0, + STD_VIDEO_AV1_LEVEL_2_1 = 1, + STD_VIDEO_AV1_LEVEL_2_2 = 2, + STD_VIDEO_AV1_LEVEL_2_3 = 3, + STD_VIDEO_AV1_LEVEL_3_0 = 4, + STD_VIDEO_AV1_LEVEL_3_1 = 5, + STD_VIDEO_AV1_LEVEL_3_2 = 6, + STD_VIDEO_AV1_LEVEL_3_3 = 7, + STD_VIDEO_AV1_LEVEL_4_0 = 8, + STD_VIDEO_AV1_LEVEL_4_1 = 9, + STD_VIDEO_AV1_LEVEL_4_2 = 10, + STD_VIDEO_AV1_LEVEL_4_3 = 11, + STD_VIDEO_AV1_LEVEL_5_0 = 12, + STD_VIDEO_AV1_LEVEL_5_1 = 13, + STD_VIDEO_AV1_LEVEL_5_2 = 14, + STD_VIDEO_AV1_LEVEL_5_3 = 15, + STD_VIDEO_AV1_LEVEL_6_0 = 16, + STD_VIDEO_AV1_LEVEL_6_1 = 17, + STD_VIDEO_AV1_LEVEL_6_2 = 18, + STD_VIDEO_AV1_LEVEL_6_3 = 19, + STD_VIDEO_AV1_LEVEL_7_0 = 20, + STD_VIDEO_AV1_LEVEL_7_1 = 21, + STD_VIDEO_AV1_LEVEL_7_2 = 22, + STD_VIDEO_AV1_LEVEL_7_3 = 23, + STD_VIDEO_AV1_LEVEL_INVALID = 0x7FFFFFFF, + STD_VIDEO_AV1_LEVEL_MAX_ENUM = 0x7FFFFFFF +} StdVideoAV1Level; + +typedef enum StdVideoAV1FrameType { + STD_VIDEO_AV1_FRAME_TYPE_KEY = 0, + STD_VIDEO_AV1_FRAME_TYPE_INTER = 1, + STD_VIDEO_AV1_FRAME_TYPE_INTRA_ONLY = 2, + STD_VIDEO_AV1_FRAME_TYPE_SWITCH = 3, + STD_VIDEO_AV1_FRAME_TYPE_INVALID = 0x7FFFFFFF, + STD_VIDEO_AV1_FRAME_TYPE_MAX_ENUM = 0x7FFFFFFF +} StdVideoAV1FrameType; + +typedef enum StdVideoAV1ReferenceName { + STD_VIDEO_AV1_REFERENCE_NAME_INTRA_FRAME = 0, + STD_VIDEO_AV1_REFERENCE_NAME_LAST_FRAME = 1, + STD_VIDEO_AV1_REFERENCE_NAME_LAST2_FRAME = 2, + STD_VIDEO_AV1_REFERENCE_NAME_LAST3_FRAME = 3, + STD_VIDEO_AV1_REFERENCE_NAME_GOLDEN_FRAME = 4, + STD_VIDEO_AV1_REFERENCE_NAME_BWDREF_FRAME = 5, + STD_VIDEO_AV1_REFERENCE_NAME_ALTREF2_FRAME = 6, + STD_VIDEO_AV1_REFERENCE_NAME_ALTREF_FRAME = 7, + STD_VIDEO_AV1_REFERENCE_NAME_INVALID = 0x7FFFFFFF, + STD_VIDEO_AV1_REFERENCE_NAME_MAX_ENUM = 0x7FFFFFFF +} StdVideoAV1ReferenceName; + +typedef enum StdVideoAV1InterpolationFilter { + STD_VIDEO_AV1_INTERPOLATION_FILTER_EIGHTTAP = 0, + STD_VIDEO_AV1_INTERPOLATION_FILTER_EIGHTTAP_SMOOTH = 1, + STD_VIDEO_AV1_INTERPOLATION_FILTER_EIGHTTAP_SHARP = 2, + STD_VIDEO_AV1_INTERPOLATION_FILTER_BILINEAR = 3, + STD_VIDEO_AV1_INTERPOLATION_FILTER_SWITCHABLE = 4, + STD_VIDEO_AV1_INTERPOLATION_FILTER_INVALID = 0x7FFFFFFF, + STD_VIDEO_AV1_INTERPOLATION_FILTER_MAX_ENUM = 0x7FFFFFFF +} StdVideoAV1InterpolationFilter; + +typedef enum StdVideoAV1TxMode { + STD_VIDEO_AV1_TX_MODE_ONLY_4X4 = 0, + STD_VIDEO_AV1_TX_MODE_LARGEST = 1, + STD_VIDEO_AV1_TX_MODE_SELECT = 2, + STD_VIDEO_AV1_TX_MODE_INVALID = 0x7FFFFFFF, + STD_VIDEO_AV1_TX_MODE_MAX_ENUM = 0x7FFFFFFF +} StdVideoAV1TxMode; + +typedef enum StdVideoAV1FrameRestorationType { + STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_NONE = 0, + STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_WIENER = 1, + STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_SGRPROJ = 2, + STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_SWITCHABLE = 3, + STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_INVALID = 0x7FFFFFFF, + STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_MAX_ENUM = 0x7FFFFFFF +} StdVideoAV1FrameRestorationType; + +typedef enum StdVideoAV1ColorPrimaries { + STD_VIDEO_AV1_COLOR_PRIMARIES_BT_709 = 1, + STD_VIDEO_AV1_COLOR_PRIMARIES_BT_UNSPECIFIED = 2, + STD_VIDEO_AV1_COLOR_PRIMARIES_BT_470_M = 4, + STD_VIDEO_AV1_COLOR_PRIMARIES_BT_470_B_G = 5, + STD_VIDEO_AV1_COLOR_PRIMARIES_BT_601 = 6, + STD_VIDEO_AV1_COLOR_PRIMARIES_SMPTE_240 = 7, + STD_VIDEO_AV1_COLOR_PRIMARIES_GENERIC_FILM = 8, + STD_VIDEO_AV1_COLOR_PRIMARIES_BT_2020 = 9, + STD_VIDEO_AV1_COLOR_PRIMARIES_XYZ = 10, + STD_VIDEO_AV1_COLOR_PRIMARIES_SMPTE_431 = 11, + STD_VIDEO_AV1_COLOR_PRIMARIES_SMPTE_432 = 12, + STD_VIDEO_AV1_COLOR_PRIMARIES_EBU_3213 = 22, + STD_VIDEO_AV1_COLOR_PRIMARIES_INVALID = 0x7FFFFFFF, + STD_VIDEO_AV1_COLOR_PRIMARIES_MAX_ENUM = 0x7FFFFFFF +} StdVideoAV1ColorPrimaries; + +typedef enum StdVideoAV1TransferCharacteristics { + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_RESERVED_0 = 0, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_709 = 1, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_UNSPECIFIED = 2, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_RESERVED_3 = 3, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_470_M = 4, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_470_B_G = 5, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_601 = 6, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_SMPTE_240 = 7, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_LINEAR = 8, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_LOG_100 = 9, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_LOG_100_SQRT10 = 10, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_IEC_61966 = 11, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_1361 = 12, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_SRGB = 13, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_2020_10_BIT = 14, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_2020_12_BIT = 15, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_SMPTE_2084 = 16, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_SMPTE_428 = 17, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_HLG = 18, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_INVALID = 0x7FFFFFFF, + STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_MAX_ENUM = 0x7FFFFFFF +} StdVideoAV1TransferCharacteristics; + +typedef enum StdVideoAV1MatrixCoefficients { + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_IDENTITY = 0, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_BT_709 = 1, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_UNSPECIFIED = 2, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_RESERVED_3 = 3, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_FCC = 4, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_BT_470_B_G = 5, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_BT_601 = 6, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_SMPTE_240 = 7, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_SMPTE_YCGCO = 8, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_BT_2020_NCL = 9, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_BT_2020_CL = 10, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_SMPTE_2085 = 11, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_CHROMAT_NCL = 12, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_CHROMAT_CL = 13, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_ICTCP = 14, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_INVALID = 0x7FFFFFFF, + STD_VIDEO_AV1_MATRIX_COEFFICIENTS_MAX_ENUM = 0x7FFFFFFF +} StdVideoAV1MatrixCoefficients; + +typedef enum StdVideoAV1ChromaSamplePosition { + STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_UNKNOWN = 0, + STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_VERTICAL = 1, + STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_COLOCATED = 2, + STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_RESERVED = 3, + STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_INVALID = 0x7FFFFFFF, + STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_MAX_ENUM = 0x7FFFFFFF +} StdVideoAV1ChromaSamplePosition; +typedef struct StdVideoAV1ColorConfigFlags { + uint32_t mono_chrome : 1; + uint32_t color_range : 1; + uint32_t separate_uv_delta_q : 1; + uint32_t color_description_present_flag : 1; + uint32_t reserved : 28; +} StdVideoAV1ColorConfigFlags; + +typedef struct StdVideoAV1ColorConfig { + StdVideoAV1ColorConfigFlags flags; + uint8_t BitDepth; + uint8_t subsampling_x; + uint8_t subsampling_y; + uint8_t reserved1; + StdVideoAV1ColorPrimaries color_primaries; + StdVideoAV1TransferCharacteristics transfer_characteristics; + StdVideoAV1MatrixCoefficients matrix_coefficients; + StdVideoAV1ChromaSamplePosition chroma_sample_position; +} StdVideoAV1ColorConfig; + +typedef struct StdVideoAV1TimingInfoFlags { + uint32_t equal_picture_interval : 1; + uint32_t reserved : 31; +} StdVideoAV1TimingInfoFlags; + +typedef struct StdVideoAV1TimingInfo { + StdVideoAV1TimingInfoFlags flags; + uint32_t num_units_in_display_tick; + uint32_t time_scale; + uint32_t num_ticks_per_picture_minus_1; +} StdVideoAV1TimingInfo; + +typedef struct StdVideoAV1LoopFilterFlags { + uint32_t loop_filter_delta_enabled : 1; + uint32_t loop_filter_delta_update : 1; + uint32_t reserved : 30; +} StdVideoAV1LoopFilterFlags; + +typedef struct StdVideoAV1LoopFilter { + StdVideoAV1LoopFilterFlags flags; + uint8_t loop_filter_level[STD_VIDEO_AV1_MAX_LOOP_FILTER_STRENGTHS]; + uint8_t loop_filter_sharpness; + uint8_t update_ref_delta; + int8_t loop_filter_ref_deltas[STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME]; + uint8_t update_mode_delta; + int8_t loop_filter_mode_deltas[STD_VIDEO_AV1_LOOP_FILTER_ADJUSTMENTS]; +} StdVideoAV1LoopFilter; + +typedef struct StdVideoAV1QuantizationFlags { + uint32_t using_qmatrix : 1; + uint32_t diff_uv_delta : 1; + uint32_t reserved : 30; +} StdVideoAV1QuantizationFlags; + +typedef struct StdVideoAV1Quantization { + StdVideoAV1QuantizationFlags flags; + uint8_t base_q_idx; + int8_t DeltaQYDc; + int8_t DeltaQUDc; + int8_t DeltaQUAc; + int8_t DeltaQVDc; + int8_t DeltaQVAc; + uint8_t qm_y; + uint8_t qm_u; + uint8_t qm_v; +} StdVideoAV1Quantization; + +typedef struct StdVideoAV1Segmentation { + uint8_t FeatureEnabled[STD_VIDEO_AV1_MAX_SEGMENTS]; + int16_t FeatureData[STD_VIDEO_AV1_MAX_SEGMENTS][STD_VIDEO_AV1_SEG_LVL_MAX]; +} StdVideoAV1Segmentation; + +typedef struct StdVideoAV1TileInfoFlags { + uint32_t uniform_tile_spacing_flag : 1; + uint32_t reserved : 31; +} StdVideoAV1TileInfoFlags; + +typedef struct StdVideoAV1TileInfo { + StdVideoAV1TileInfoFlags flags; + uint8_t TileCols; + uint8_t TileRows; + uint16_t context_update_tile_id; + uint8_t tile_size_bytes_minus_1; + uint8_t reserved1[7]; + const uint16_t* pMiColStarts; + const uint16_t* pMiRowStarts; + const uint16_t* pWidthInSbsMinus1; + const uint16_t* pHeightInSbsMinus1; +} StdVideoAV1TileInfo; + +typedef struct StdVideoAV1CDEF { + uint8_t cdef_damping_minus_3; + uint8_t cdef_bits; + uint8_t cdef_y_pri_strength[STD_VIDEO_AV1_MAX_CDEF_FILTER_STRENGTHS]; + uint8_t cdef_y_sec_strength[STD_VIDEO_AV1_MAX_CDEF_FILTER_STRENGTHS]; + uint8_t cdef_uv_pri_strength[STD_VIDEO_AV1_MAX_CDEF_FILTER_STRENGTHS]; + uint8_t cdef_uv_sec_strength[STD_VIDEO_AV1_MAX_CDEF_FILTER_STRENGTHS]; +} StdVideoAV1CDEF; + +typedef struct StdVideoAV1LoopRestoration { + StdVideoAV1FrameRestorationType FrameRestorationType[STD_VIDEO_AV1_MAX_NUM_PLANES]; + uint16_t LoopRestorationSize[STD_VIDEO_AV1_MAX_NUM_PLANES]; +} StdVideoAV1LoopRestoration; + +typedef struct StdVideoAV1GlobalMotion { + uint8_t GmType[STD_VIDEO_AV1_NUM_REF_FRAMES]; + int32_t gm_params[STD_VIDEO_AV1_NUM_REF_FRAMES][STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS]; +} StdVideoAV1GlobalMotion; + +typedef struct StdVideoAV1FilmGrainFlags { + uint32_t chroma_scaling_from_luma : 1; + uint32_t overlap_flag : 1; + uint32_t clip_to_restricted_range : 1; + uint32_t update_grain : 1; + uint32_t reserved : 28; +} StdVideoAV1FilmGrainFlags; + +typedef struct StdVideoAV1FilmGrain { + StdVideoAV1FilmGrainFlags flags; + uint8_t grain_scaling_minus_8; + uint8_t ar_coeff_lag; + uint8_t ar_coeff_shift_minus_6; + uint8_t grain_scale_shift; + uint16_t grain_seed; + uint8_t film_grain_params_ref_idx; + uint8_t num_y_points; + uint8_t point_y_value[STD_VIDEO_AV1_MAX_NUM_Y_POINTS]; + uint8_t point_y_scaling[STD_VIDEO_AV1_MAX_NUM_Y_POINTS]; + uint8_t num_cb_points; + uint8_t point_cb_value[STD_VIDEO_AV1_MAX_NUM_CB_POINTS]; + uint8_t point_cb_scaling[STD_VIDEO_AV1_MAX_NUM_CB_POINTS]; + uint8_t num_cr_points; + uint8_t point_cr_value[STD_VIDEO_AV1_MAX_NUM_CR_POINTS]; + uint8_t point_cr_scaling[STD_VIDEO_AV1_MAX_NUM_CR_POINTS]; + int8_t ar_coeffs_y_plus_128[STD_VIDEO_AV1_MAX_NUM_POS_LUMA]; + int8_t ar_coeffs_cb_plus_128[STD_VIDEO_AV1_MAX_NUM_POS_CHROMA]; + int8_t ar_coeffs_cr_plus_128[STD_VIDEO_AV1_MAX_NUM_POS_CHROMA]; + uint8_t cb_mult; + uint8_t cb_luma_mult; + uint16_t cb_offset; + uint8_t cr_mult; + uint8_t cr_luma_mult; + uint16_t cr_offset; +} StdVideoAV1FilmGrain; + +typedef struct StdVideoAV1SequenceHeaderFlags { + uint32_t still_picture : 1; + uint32_t reduced_still_picture_header : 1; + uint32_t use_128x128_superblock : 1; + uint32_t enable_filter_intra : 1; + uint32_t enable_intra_edge_filter : 1; + uint32_t enable_interintra_compound : 1; + uint32_t enable_masked_compound : 1; + uint32_t enable_warped_motion : 1; + uint32_t enable_dual_filter : 1; + uint32_t enable_order_hint : 1; + uint32_t enable_jnt_comp : 1; + uint32_t enable_ref_frame_mvs : 1; + uint32_t frame_id_numbers_present_flag : 1; + uint32_t enable_superres : 1; + uint32_t enable_cdef : 1; + uint32_t enable_restoration : 1; + uint32_t film_grain_params_present : 1; + uint32_t timing_info_present_flag : 1; + uint32_t initial_display_delay_present_flag : 1; + uint32_t reserved : 13; +} StdVideoAV1SequenceHeaderFlags; + +typedef struct StdVideoAV1SequenceHeader { + StdVideoAV1SequenceHeaderFlags flags; + StdVideoAV1Profile seq_profile; + uint8_t frame_width_bits_minus_1; + uint8_t frame_height_bits_minus_1; + uint16_t max_frame_width_minus_1; + uint16_t max_frame_height_minus_1; + uint8_t delta_frame_id_length_minus_2; + uint8_t additional_frame_id_length_minus_1; + uint8_t order_hint_bits_minus_1; + uint8_t seq_force_integer_mv; + uint8_t seq_force_screen_content_tools; + uint8_t reserved1[5]; + const StdVideoAV1ColorConfig* pColorConfig; + const StdVideoAV1TimingInfo* pTimingInfo; +} StdVideoAV1SequenceHeader; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/vk_video/vulkan_video_codec_av1std_decode.h b/external/vk_video/vulkan_video_codec_av1std_decode.h new file mode 100644 index 0000000..6b8130c --- /dev/null +++ b/external/vk_video/vulkan_video_codec_av1std_decode.h @@ -0,0 +1,109 @@ +#ifndef VULKAN_VIDEO_CODEC_AV1STD_DECODE_H_ +#define VULKAN_VIDEO_CODEC_AV1STD_DECODE_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// vulkan_video_codec_av1std_decode is a preprocessor guard. Do not pass it to API calls. +#define vulkan_video_codec_av1std_decode 1 +#include "vulkan_video_codec_av1std.h" + +#define VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0) + +#define VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_API_VERSION_1_0_0 +#define VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_av1_decode" +typedef struct StdVideoDecodeAV1PictureInfoFlags { + uint32_t error_resilient_mode : 1; + uint32_t disable_cdf_update : 1; + uint32_t use_superres : 1; + uint32_t render_and_frame_size_different : 1; + uint32_t allow_screen_content_tools : 1; + uint32_t is_filter_switchable : 1; + uint32_t force_integer_mv : 1; + uint32_t frame_size_override_flag : 1; + uint32_t buffer_removal_time_present_flag : 1; + uint32_t allow_intrabc : 1; + uint32_t frame_refs_short_signaling : 1; + uint32_t allow_high_precision_mv : 1; + uint32_t is_motion_mode_switchable : 1; + uint32_t use_ref_frame_mvs : 1; + uint32_t disable_frame_end_update_cdf : 1; + uint32_t allow_warped_motion : 1; + uint32_t reduced_tx_set : 1; + uint32_t reference_select : 1; + uint32_t skip_mode_present : 1; + uint32_t delta_q_present : 1; + uint32_t delta_lf_present : 1; + uint32_t delta_lf_multi : 1; + uint32_t segmentation_enabled : 1; + uint32_t segmentation_update_map : 1; + uint32_t segmentation_temporal_update : 1; + uint32_t segmentation_update_data : 1; + uint32_t UsesLr : 1; + uint32_t usesChromaLr : 1; + uint32_t apply_grain : 1; + uint32_t reserved : 3; +} StdVideoDecodeAV1PictureInfoFlags; + +typedef struct StdVideoDecodeAV1PictureInfo { + StdVideoDecodeAV1PictureInfoFlags flags; + StdVideoAV1FrameType frame_type; + uint32_t current_frame_id; + uint8_t OrderHint; + uint8_t primary_ref_frame; + uint8_t refresh_frame_flags; + uint8_t reserved1; + StdVideoAV1InterpolationFilter interpolation_filter; + StdVideoAV1TxMode TxMode; + uint8_t delta_q_res; + uint8_t delta_lf_res; + uint8_t SkipModeFrame[STD_VIDEO_AV1_SKIP_MODE_FRAMES]; + uint8_t coded_denom; + uint8_t reserved2[3]; + uint8_t OrderHints[STD_VIDEO_AV1_NUM_REF_FRAMES]; + uint32_t expectedFrameId[STD_VIDEO_AV1_NUM_REF_FRAMES]; + const StdVideoAV1TileInfo* pTileInfo; + const StdVideoAV1Quantization* pQuantization; + const StdVideoAV1Segmentation* pSegmentation; + const StdVideoAV1LoopFilter* pLoopFilter; + const StdVideoAV1CDEF* pCDEF; + const StdVideoAV1LoopRestoration* pLoopRestoration; + const StdVideoAV1GlobalMotion* pGlobalMotion; + const StdVideoAV1FilmGrain* pFilmGrain; +} StdVideoDecodeAV1PictureInfo; + +typedef struct StdVideoDecodeAV1ReferenceInfoFlags { + uint32_t disable_frame_end_update_cdf : 1; + uint32_t segmentation_enabled : 1; + uint32_t reserved : 30; +} StdVideoDecodeAV1ReferenceInfoFlags; + +typedef struct StdVideoDecodeAV1ReferenceInfo { + StdVideoDecodeAV1ReferenceInfoFlags flags; + uint8_t frame_type; + uint8_t RefFrameSignBias; + uint8_t OrderHint; + uint8_t SavedOrderHints[STD_VIDEO_AV1_NUM_REF_FRAMES]; +} StdVideoDecodeAV1ReferenceInfo; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/vk_video/vulkan_video_codec_h264std.h b/external/vk_video/vulkan_video_codec_h264std.h index d3ebec6..6d27af3 100644 --- a/external/vk_video/vulkan_video_codec_h264std.h +++ b/external/vk_video/vulkan_video_codec_h264std.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODEC_H264STD_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,8 +19,9 @@ extern "C" { +// vulkan_video_codec_h264std is a preprocessor guard. Do not pass it to API calls. #define vulkan_video_codec_h264std 1 -#include +#include "vulkan_video_codecs_common.h" #define STD_VIDEO_H264_CPB_CNT_LIST_SIZE 32 #define STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS 6 #define STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS 16 @@ -28,6 +29,7 @@ extern "C" { #define STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS 64 #define STD_VIDEO_H264_MAX_NUM_LIST_REF 32 #define STD_VIDEO_H264_MAX_CHROMA_PLANES 2 +#define STD_VIDEO_H264_NO_REFERENCE_PICTURE 0xFF typedef enum StdVideoH264ChromaFormatIdc { STD_VIDEO_H264_CHROMA_FORMAT_IDC_MONOCHROME = 0, diff --git a/external/vk_video/vulkan_video_codec_h264std_decode.h b/external/vk_video/vulkan_video_codec_h264std_decode.h index b1e7942..439cb88 100644 --- a/external/vk_video/vulkan_video_codec_h264std_decode.h +++ b/external/vk_video/vulkan_video_codec_h264std_decode.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODEC_H264STD_DECODE_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,13 +19,15 @@ extern "C" { +// vulkan_video_codec_h264std_decode is a preprocessor guard. Do not pass it to API calls. #define vulkan_video_codec_h264std_decode 1 +#include "vulkan_video_codec_h264std.h" #define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0) -#define STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_LIST_SIZE 2 #define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_API_VERSION_1_0_0 #define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h264_decode" +#define STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_LIST_SIZE 2 typedef enum StdVideoDecodeH264FieldOrderCount { STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_TOP = 0, diff --git a/external/vk_video/vulkan_video_codec_h264std_encode.h b/external/vk_video/vulkan_video_codec_h264std_encode.h index 7bd96aa..9e24aa5 100644 --- a/external/vk_video/vulkan_video_codec_h264std_encode.h +++ b/external/vk_video/vulkan_video_codec_h264std_encode.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODEC_H264STD_ENCODE_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,11 +19,13 @@ extern "C" { +// vulkan_video_codec_h264std_encode is a preprocessor guard. Do not pass it to API calls. #define vulkan_video_codec_h264std_encode 1 -// Vulkan 0.9 provisional Vulkan video H.264 encode std specification version number -#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_0_9_8 VK_MAKE_VIDEO_STD_VERSION(0, 9, 8) +#include "vulkan_video_codec_h264std.h" -#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_0_9_8 +#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0) + +#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_1_0_0 #define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h264_encode" typedef struct StdVideoEncodeH264WeightTableFlags { uint32_t luma_weight_l0_flag; @@ -49,25 +51,28 @@ typedef struct StdVideoEncodeH264WeightTable { typedef struct StdVideoEncodeH264SliceHeaderFlags { uint32_t direct_spatial_mv_pred_flag : 1; uint32_t num_ref_idx_active_override_flag : 1; - uint32_t no_output_of_prior_pics_flag : 1; - uint32_t adaptive_ref_pic_marking_mode_flag : 1; - uint32_t no_prior_references_available_flag : 1; + uint32_t reserved : 30; } StdVideoEncodeH264SliceHeaderFlags; typedef struct StdVideoEncodeH264PictureInfoFlags { - uint32_t idr_flag : 1; - uint32_t is_reference_flag : 1; - uint32_t used_for_long_term_reference : 1; + uint32_t IdrPicFlag : 1; + uint32_t is_reference : 1; + uint32_t no_output_of_prior_pics_flag : 1; + uint32_t long_term_reference_flag : 1; + uint32_t adaptive_ref_pic_marking_mode_flag : 1; + uint32_t reserved : 27; } StdVideoEncodeH264PictureInfoFlags; typedef struct StdVideoEncodeH264ReferenceInfoFlags { uint32_t used_for_long_term_reference : 1; + uint32_t reserved : 31; } StdVideoEncodeH264ReferenceInfoFlags; -typedef struct StdVideoEncodeH264RefMgmtFlags { - uint32_t ref_pic_list_modification_l0_flag : 1; - uint32_t ref_pic_list_modification_l1_flag : 1; -} StdVideoEncodeH264RefMgmtFlags; +typedef struct StdVideoEncodeH264ReferenceListsInfoFlags { + uint32_t ref_pic_list_modification_flag_l0 : 1; + uint32_t ref_pic_list_modification_flag_l1 : 1; + uint32_t reserved : 30; +} StdVideoEncodeH264ReferenceListsInfoFlags; typedef struct StdVideoEncodeH264RefListModEntry { StdVideoH264ModificationOfPicNumsIdc modification_of_pic_nums_idc; @@ -76,51 +81,61 @@ typedef struct StdVideoEncodeH264RefListModEntry { } StdVideoEncodeH264RefListModEntry; typedef struct StdVideoEncodeH264RefPicMarkingEntry { - StdVideoH264MemMgmtControlOp operation; + StdVideoH264MemMgmtControlOp memory_management_control_operation; uint16_t difference_of_pic_nums_minus1; uint16_t long_term_pic_num; uint16_t long_term_frame_idx; uint16_t max_long_term_frame_idx_plus1; } StdVideoEncodeH264RefPicMarkingEntry; -typedef struct StdVideoEncodeH264RefMemMgmtCtrlOperations { - StdVideoEncodeH264RefMgmtFlags flags; +typedef struct StdVideoEncodeH264ReferenceListsInfo { + StdVideoEncodeH264ReferenceListsInfoFlags flags; + uint8_t num_ref_idx_l0_active_minus1; + uint8_t num_ref_idx_l1_active_minus1; + uint8_t RefPicList0[STD_VIDEO_H264_MAX_NUM_LIST_REF]; + uint8_t RefPicList1[STD_VIDEO_H264_MAX_NUM_LIST_REF]; uint8_t refList0ModOpCount; - const StdVideoEncodeH264RefListModEntry* pRefList0ModOperations; uint8_t refList1ModOpCount; - const StdVideoEncodeH264RefListModEntry* pRefList1ModOperations; uint8_t refPicMarkingOpCount; + uint8_t reserved1[7]; + const StdVideoEncodeH264RefListModEntry* pRefList0ModOperations; + const StdVideoEncodeH264RefListModEntry* pRefList1ModOperations; const StdVideoEncodeH264RefPicMarkingEntry* pRefPicMarkingOperations; -} StdVideoEncodeH264RefMemMgmtCtrlOperations; +} StdVideoEncodeH264ReferenceListsInfo; typedef struct StdVideoEncodeH264PictureInfo { - StdVideoEncodeH264PictureInfoFlags flags; - uint8_t seq_parameter_set_id; - uint8_t pic_parameter_set_id; - StdVideoH264PictureType pictureType; - uint32_t frame_num; - int32_t PicOrderCnt; + StdVideoEncodeH264PictureInfoFlags flags; + uint8_t seq_parameter_set_id; + uint8_t pic_parameter_set_id; + uint16_t idr_pic_id; + StdVideoH264PictureType primary_pic_type; + uint32_t frame_num; + int32_t PicOrderCnt; + uint8_t temporal_id; + uint8_t reserved1[3]; + const StdVideoEncodeH264ReferenceListsInfo* pRefLists; } StdVideoEncodeH264PictureInfo; typedef struct StdVideoEncodeH264ReferenceInfo { StdVideoEncodeH264ReferenceInfoFlags flags; + StdVideoH264PictureType primary_pic_type; uint32_t FrameNum; int32_t PicOrderCnt; uint16_t long_term_pic_num; uint16_t long_term_frame_idx; + uint8_t temporal_id; } StdVideoEncodeH264ReferenceInfo; typedef struct StdVideoEncodeH264SliceHeader { StdVideoEncodeH264SliceHeaderFlags flags; uint32_t first_mb_in_slice; StdVideoH264SliceType slice_type; - uint16_t idr_pic_id; - uint8_t num_ref_idx_l0_active_minus1; - uint8_t num_ref_idx_l1_active_minus1; - StdVideoH264CabacInitIdc cabac_init_idc; - StdVideoH264DisableDeblockingFilterIdc disable_deblocking_filter_idc; int8_t slice_alpha_c0_offset_div2; int8_t slice_beta_offset_div2; + int8_t slice_qp_delta; + uint8_t reserved1; + StdVideoH264CabacInitIdc cabac_init_idc; + StdVideoH264DisableDeblockingFilterIdc disable_deblocking_filter_idc; const StdVideoEncodeH264WeightTable* pWeightTable; } StdVideoEncodeH264SliceHeader; diff --git a/external/vk_video/vulkan_video_codec_h265std.h b/external/vk_video/vulkan_video_codec_h265std.h index 862f881..d0a1bac 100644 --- a/external/vk_video/vulkan_video_codec_h265std.h +++ b/external/vk_video/vulkan_video_codec_h265std.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODEC_H265STD_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,9 +19,11 @@ extern "C" { +// vulkan_video_codec_h265std is a preprocessor guard. Do not pass it to API calls. #define vulkan_video_codec_h265std 1 -#define STD_VIDEO_H265_SUBLAYERS_LIST_SIZE 7 +#include "vulkan_video_codecs_common.h" #define STD_VIDEO_H265_CPB_CNT_LIST_SIZE 32 +#define STD_VIDEO_H265_SUBLAYERS_LIST_SIZE 7 #define STD_VIDEO_H265_SCALING_LIST_4X4_NUM_LISTS 6 #define STD_VIDEO_H265_SCALING_LIST_4X4_NUM_ELEMENTS 16 #define STD_VIDEO_H265_SCALING_LIST_8X8_NUM_LISTS 6 @@ -30,18 +32,19 @@ extern "C" { #define STD_VIDEO_H265_SCALING_LIST_16X16_NUM_ELEMENTS 64 #define STD_VIDEO_H265_SCALING_LIST_32X32_NUM_LISTS 2 #define STD_VIDEO_H265_SCALING_LIST_32X32_NUM_ELEMENTS 64 -#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMPONENTS_LIST_SIZE 3 -#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMP_ENTRIES_LIST_SIZE 128 -#define STD_VIDEO_H265_MAX_DPB_SIZE 16 -#define STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS 32 #define STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE 6 #define STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_COLS_LIST_SIZE 19 #define STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_ROWS_LIST_SIZE 21 +#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMPONENTS_LIST_SIZE 3 +#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMP_ENTRIES_LIST_SIZE 128 #define STD_VIDEO_H265_MAX_NUM_LIST_REF 15 #define STD_VIDEO_H265_MAX_CHROMA_PLANES 2 #define STD_VIDEO_H265_MAX_SHORT_TERM_REF_PIC_SETS 64 +#define STD_VIDEO_H265_MAX_DPB_SIZE 16 +#define STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS 32 #define STD_VIDEO_H265_MAX_LONG_TERM_PICS 16 #define STD_VIDEO_H265_MAX_DELTA_POC 48 +#define STD_VIDEO_H265_NO_REFERENCE_PICTURE 0xFF typedef enum StdVideoH265ChromaFormatIdc { STD_VIDEO_H265_CHROMA_FORMAT_IDC_MONOCHROME = 0, diff --git a/external/vk_video/vulkan_video_codec_h265std_decode.h b/external/vk_video/vulkan_video_codec_h265std_decode.h index d8660d1..0178793 100644 --- a/external/vk_video/vulkan_video_codec_h265std_decode.h +++ b/external/vk_video/vulkan_video_codec_h265std_decode.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODEC_H265STD_DECODE_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,13 +19,15 @@ extern "C" { +// vulkan_video_codec_h265std_decode is a preprocessor guard. Do not pass it to API calls. #define vulkan_video_codec_h265std_decode 1 +#include "vulkan_video_codec_h265std.h" #define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0) -#define STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE 8 #define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_API_VERSION_1_0_0 #define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h265_decode" +#define STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE 8 typedef struct StdVideoDecodeH265PictureInfoFlags { uint32_t IrapPicFlag : 1; uint32_t IdrPicFlag : 1; diff --git a/external/vk_video/vulkan_video_codec_h265std_encode.h b/external/vk_video/vulkan_video_codec_h265std_encode.h index 5a419b1..ee34491 100644 --- a/external/vk_video/vulkan_video_codec_h265std_encode.h +++ b/external/vk_video/vulkan_video_codec_h265std_encode.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODEC_H265STD_ENCODE_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,11 +19,13 @@ extern "C" { +// vulkan_video_codec_h265std_encode is a preprocessor guard. Do not pass it to API calls. #define vulkan_video_codec_h265std_encode 1 -// Vulkan 0.9 provisional Vulkan video H.265 encode std specification version number -#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_0_9_9 VK_MAKE_VIDEO_STD_VERSION(0, 9, 9) +#include "vulkan_video_codec_h265std.h" -#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_0_9_9 +#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0) + +#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_1_0_0 #define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h265_encode" typedef struct StdVideoEncodeH265WeightTableFlags { uint16_t luma_weight_l0_flag; @@ -48,11 +50,7 @@ typedef struct StdVideoEncodeH265WeightTable { typedef struct StdVideoEncodeH265SliceSegmentHeaderFlags { uint32_t first_slice_segment_in_pic_flag : 1; - uint32_t no_output_of_prior_pics_flag : 1; uint32_t dependent_slice_segment_flag : 1; - uint32_t pic_output_flag : 1; - uint32_t short_term_ref_pic_set_sps_flag : 1; - uint32_t slice_temporal_mvp_enable_flag : 1; uint32_t slice_sao_luma_flag : 1; uint32_t slice_sao_chroma_flag : 1; uint32_t num_ref_idx_active_override_flag : 1; @@ -63,9 +61,57 @@ typedef struct StdVideoEncodeH265SliceSegmentHeaderFlags { uint32_t slice_deblocking_filter_disabled_flag : 1; uint32_t collocated_from_l0_flag : 1; uint32_t slice_loop_filter_across_slices_enabled_flag : 1; + uint32_t reserved : 20; } StdVideoEncodeH265SliceSegmentHeaderFlags; -typedef struct StdVideoEncodeH265SliceSegmentLongTermRefPics { +typedef struct StdVideoEncodeH265SliceSegmentHeader { + StdVideoEncodeH265SliceSegmentHeaderFlags flags; + StdVideoH265SliceType slice_type; + uint32_t slice_segment_address; + uint8_t collocated_ref_idx; + uint8_t MaxNumMergeCand; + int8_t slice_cb_qp_offset; + int8_t slice_cr_qp_offset; + int8_t slice_beta_offset_div2; + int8_t slice_tc_offset_div2; + int8_t slice_act_y_qp_offset; + int8_t slice_act_cb_qp_offset; + int8_t slice_act_cr_qp_offset; + int8_t slice_qp_delta; + uint16_t reserved1; + const StdVideoEncodeH265WeightTable* pWeightTable; +} StdVideoEncodeH265SliceSegmentHeader; + +typedef struct StdVideoEncodeH265ReferenceListsInfoFlags { + uint32_t ref_pic_list_modification_flag_l0 : 1; + uint32_t ref_pic_list_modification_flag_l1 : 1; + uint32_t reserved : 30; +} StdVideoEncodeH265ReferenceListsInfoFlags; + +typedef struct StdVideoEncodeH265ReferenceListsInfo { + StdVideoEncodeH265ReferenceListsInfoFlags flags; + uint8_t num_ref_idx_l0_active_minus1; + uint8_t num_ref_idx_l1_active_minus1; + uint8_t RefPicList0[STD_VIDEO_H265_MAX_NUM_LIST_REF]; + uint8_t RefPicList1[STD_VIDEO_H265_MAX_NUM_LIST_REF]; + uint8_t list_entry_l0[STD_VIDEO_H265_MAX_NUM_LIST_REF]; + uint8_t list_entry_l1[STD_VIDEO_H265_MAX_NUM_LIST_REF]; +} StdVideoEncodeH265ReferenceListsInfo; + +typedef struct StdVideoEncodeH265PictureInfoFlags { + uint32_t is_reference : 1; + uint32_t IrapPicFlag : 1; + uint32_t used_for_long_term_reference : 1; + uint32_t discardable_flag : 1; + uint32_t cross_layer_bla_flag : 1; + uint32_t pic_output_flag : 1; + uint32_t no_output_of_prior_pics_flag : 1; + uint32_t short_term_ref_pic_set_sps_flag : 1; + uint32_t slice_temporal_mvp_enabled_flag : 1; + uint32_t reserved : 23; +} StdVideoEncodeH265PictureInfoFlags; + +typedef struct StdVideoEncodeH265LongTermRefPics { uint8_t num_long_term_sps; uint8_t num_long_term_pics; uint8_t lt_idx_sps[STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS]; @@ -73,67 +119,32 @@ typedef struct StdVideoEncodeH265SliceSegmentLongTermRefPics { uint16_t used_by_curr_pic_lt_flag; uint8_t delta_poc_msb_present_flag[STD_VIDEO_H265_MAX_DELTA_POC]; uint8_t delta_poc_msb_cycle_lt[STD_VIDEO_H265_MAX_DELTA_POC]; -} StdVideoEncodeH265SliceSegmentLongTermRefPics; - -typedef struct StdVideoEncodeH265SliceSegmentHeader { - StdVideoEncodeH265SliceSegmentHeaderFlags flags; - StdVideoH265SliceType slice_type; - uint32_t slice_segment_address; - uint8_t short_term_ref_pic_set_idx; - uint8_t collocated_ref_idx; - uint8_t num_ref_idx_l0_active_minus1; - uint8_t num_ref_idx_l1_active_minus1; - uint8_t MaxNumMergeCand; - int8_t slice_cb_qp_offset; - int8_t slice_cr_qp_offset; - int8_t slice_beta_offset_div2; - int8_t slice_tc_offset_div2; - int8_t slice_act_y_qp_offset; - int8_t slice_act_cb_qp_offset; - int8_t slice_act_cr_qp_offset; - const StdVideoH265ShortTermRefPicSet* pShortTermRefPicSet; - const StdVideoEncodeH265SliceSegmentLongTermRefPics* pLongTermRefPics; - const StdVideoEncodeH265WeightTable* pWeightTable; -} StdVideoEncodeH265SliceSegmentHeader; - -typedef struct StdVideoEncodeH265ReferenceModificationFlags { - uint32_t ref_pic_list_modification_flag_l0 : 1; - uint32_t ref_pic_list_modification_flag_l1 : 1; -} StdVideoEncodeH265ReferenceModificationFlags; - -typedef struct StdVideoEncodeH265ReferenceModifications { - StdVideoEncodeH265ReferenceModificationFlags flags; - uint8_t referenceList0ModificationsCount; - const uint8_t* pReferenceList0Modifications; - uint8_t referenceList1ModificationsCount; - const uint8_t* pReferenceList1Modifications; -} StdVideoEncodeH265ReferenceModifications; - -typedef struct StdVideoEncodeH265PictureInfoFlags { - uint32_t is_reference_flag : 1; - uint32_t IrapPicFlag : 1; - uint32_t long_term_flag : 1; - uint32_t discardable_flag : 1; - uint32_t cross_layer_bla_flag : 1; -} StdVideoEncodeH265PictureInfoFlags; +} StdVideoEncodeH265LongTermRefPics; typedef struct StdVideoEncodeH265PictureInfo { - StdVideoEncodeH265PictureInfoFlags flags; - StdVideoH265PictureType PictureType; - uint8_t sps_video_parameter_set_id; - uint8_t pps_seq_parameter_set_id; - uint8_t pps_pic_parameter_set_id; - int32_t PicOrderCntVal; - uint8_t TemporalId; + StdVideoEncodeH265PictureInfoFlags flags; + StdVideoH265PictureType pic_type; + uint8_t sps_video_parameter_set_id; + uint8_t pps_seq_parameter_set_id; + uint8_t pps_pic_parameter_set_id; + uint8_t short_term_ref_pic_set_idx; + int32_t PicOrderCntVal; + uint8_t TemporalId; + uint8_t reserved1[7]; + const StdVideoEncodeH265ReferenceListsInfo* pRefLists; + const StdVideoH265ShortTermRefPicSet* pShortTermRefPicSet; + const StdVideoEncodeH265LongTermRefPics* pLongTermRefPics; } StdVideoEncodeH265PictureInfo; typedef struct StdVideoEncodeH265ReferenceInfoFlags { uint32_t used_for_long_term_reference : 1; uint32_t unused_for_reference : 1; + uint32_t reserved : 30; } StdVideoEncodeH265ReferenceInfoFlags; typedef struct StdVideoEncodeH265ReferenceInfo { StdVideoEncodeH265ReferenceInfoFlags flags; + StdVideoH265PictureType pic_type; int32_t PicOrderCntVal; uint8_t TemporalId; } StdVideoEncodeH265ReferenceInfo; diff --git a/external/vk_video/vulkan_video_codecs_common.h b/external/vk_video/vulkan_video_codecs_common.h index 1e49826..5e6ef1d 100644 --- a/external/vk_video/vulkan_video_codecs_common.h +++ b/external/vk_video/vulkan_video_codecs_common.h @@ -2,7 +2,7 @@ #define VULKAN_VIDEO_CODECS_COMMON_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,12 @@ extern "C" { +// vulkan_video_codecs_common is a preprocessor guard. Do not pass it to API calls. #define vulkan_video_codecs_common 1 +#if !defined(VK_NO_STDINT_H) + #include +#endif + #define VK_MAKE_VIDEO_STD_VERSION(major, minor, patch) \ ((((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch))) diff --git a/external/vulkan/vk_icd.h b/external/vulkan/vk_icd.h new file mode 100644 index 0000000..59204a3 --- /dev/null +++ b/external/vulkan/vk_icd.h @@ -0,0 +1,244 @@ +/* + * Copyright 2015-2023 The Khronos Group Inc. + * Copyright 2015-2023 Valve Corporation + * Copyright 2015-2023 LunarG, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "vulkan.h" +#include + +// Loader-ICD version negotiation API. Versions add the following features: +// Version 0 - Initial. Doesn't support vk_icdGetInstanceProcAddr +// or vk_icdNegotiateLoaderICDInterfaceVersion. +// Version 1 - Add support for vk_icdGetInstanceProcAddr. +// Version 2 - Add Loader/ICD Interface version negotiation +// via vk_icdNegotiateLoaderICDInterfaceVersion. +// Version 3 - Add ICD creation/destruction of KHR_surface objects. +// Version 4 - Add unknown physical device extension querying via +// vk_icdGetPhysicalDeviceProcAddr. +// Version 5 - Tells ICDs that the loader is now paying attention to the +// application version of Vulkan passed into the ApplicationInfo +// structure during vkCreateInstance. This will tell the ICD +// that if the loader is older, it should automatically fail a +// call for any API version > 1.0. Otherwise, the loader will +// manually determine if it can support the expected version. +// Version 6 - Add support for vk_icdEnumerateAdapterPhysicalDevices. +// Version 7 - If an ICD supports any of the following functions, they must be +// queryable with vk_icdGetInstanceProcAddr: +// vk_icdNegotiateLoaderICDInterfaceVersion +// vk_icdGetPhysicalDeviceProcAddr +// vk_icdEnumerateAdapterPhysicalDevices (Windows only) +// In addition, these functions no longer need to be exported directly. +// This version allows drivers provided through the extension +// VK_LUNARG_direct_driver_loading be able to support the entire +// Driver-Loader interface. + +#define CURRENT_LOADER_ICD_INTERFACE_VERSION 7 +#define MIN_SUPPORTED_LOADER_ICD_INTERFACE_VERSION 0 +#define MIN_PHYS_DEV_EXTENSION_ICD_INTERFACE_VERSION 4 + +// Old typedefs that don't follow a proper naming convention but are preserved for compatibility +typedef VkResult(VKAPI_PTR *PFN_vkNegotiateLoaderICDInterfaceVersion)(uint32_t *pVersion); +// This is defined in vk_layer.h which will be found by the loader, but if an ICD is building against this +// file directly, it won't be found. +#ifndef PFN_GetPhysicalDeviceProcAddr +typedef PFN_vkVoidFunction(VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char *pName); +#endif + +// Typedefs for loader/ICD interface +typedef VkResult (VKAPI_PTR *PFN_vk_icdNegotiateLoaderICDInterfaceVersion)(uint32_t* pVersion); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vk_icdGetInstanceProcAddr)(VkInstance instance, const char* pName); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vk_icdGetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName); +#if defined(VK_USE_PLATFORM_WIN32_KHR) +typedef VkResult (VKAPI_PTR *PFN_vk_icdEnumerateAdapterPhysicalDevices)(VkInstance instance, LUID adapterLUID, + uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); +#endif + +// Prototypes for loader/ICD interface +#if !defined(VK_NO_PROTOTYPES) +#ifdef __cplusplus +extern "C" { +#endif + VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pVersion); + VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName); + VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName); +#if defined(VK_USE_PLATFORM_WIN32_KHR) + VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID, + uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); +#endif +#ifdef __cplusplus +} +#endif +#endif + +/* + * The ICD must reserve space for a pointer for the loader's dispatch + * table, at the start of . + * The ICD must initialize this variable using the SET_LOADER_MAGIC_VALUE macro. + */ + +#define ICD_LOADER_MAGIC 0x01CDC0DE + +typedef union { + uintptr_t loaderMagic; + void *loaderData; +} VK_LOADER_DATA; + +static inline void set_loader_magic_value(void *pNewObject) { + VK_LOADER_DATA *loader_info = (VK_LOADER_DATA *)pNewObject; + loader_info->loaderMagic = ICD_LOADER_MAGIC; +} + +static inline bool valid_loader_magic_value(void *pNewObject) { + const VK_LOADER_DATA *loader_info = (VK_LOADER_DATA *)pNewObject; + return (loader_info->loaderMagic & 0xffffffff) == ICD_LOADER_MAGIC; +} + +/* + * Windows and Linux ICDs will treat VkSurfaceKHR as a pointer to a struct that + * contains the platform-specific connection and surface information. + */ +typedef enum { + VK_ICD_WSI_PLATFORM_MIR, + VK_ICD_WSI_PLATFORM_WAYLAND, + VK_ICD_WSI_PLATFORM_WIN32, + VK_ICD_WSI_PLATFORM_XCB, + VK_ICD_WSI_PLATFORM_XLIB, + VK_ICD_WSI_PLATFORM_ANDROID, + VK_ICD_WSI_PLATFORM_MACOS, + VK_ICD_WSI_PLATFORM_IOS, + VK_ICD_WSI_PLATFORM_DISPLAY, + VK_ICD_WSI_PLATFORM_HEADLESS, + VK_ICD_WSI_PLATFORM_METAL, + VK_ICD_WSI_PLATFORM_DIRECTFB, + VK_ICD_WSI_PLATFORM_VI, + VK_ICD_WSI_PLATFORM_GGP, + VK_ICD_WSI_PLATFORM_SCREEN, + VK_ICD_WSI_PLATFORM_FUCHSIA, +} VkIcdWsiPlatform; + +typedef struct { + VkIcdWsiPlatform platform; +} VkIcdSurfaceBase; + +#ifdef VK_USE_PLATFORM_MIR_KHR +typedef struct { + VkIcdSurfaceBase base; + MirConnection *connection; + MirSurface *mirSurface; +} VkIcdSurfaceMir; +#endif // VK_USE_PLATFORM_MIR_KHR + +#ifdef VK_USE_PLATFORM_WAYLAND_KHR +typedef struct { + VkIcdSurfaceBase base; + struct wl_display *display; + struct wl_surface *surface; +} VkIcdSurfaceWayland; +#endif // VK_USE_PLATFORM_WAYLAND_KHR + +#ifdef VK_USE_PLATFORM_WIN32_KHR +typedef struct { + VkIcdSurfaceBase base; + HINSTANCE hinstance; + HWND hwnd; +} VkIcdSurfaceWin32; +#endif // VK_USE_PLATFORM_WIN32_KHR + +#ifdef VK_USE_PLATFORM_XCB_KHR +typedef struct { + VkIcdSurfaceBase base; + xcb_connection_t *connection; + xcb_window_t window; +} VkIcdSurfaceXcb; +#endif // VK_USE_PLATFORM_XCB_KHR + +#ifdef VK_USE_PLATFORM_XLIB_KHR +typedef struct { + VkIcdSurfaceBase base; + Display *dpy; + Window window; +} VkIcdSurfaceXlib; +#endif // VK_USE_PLATFORM_XLIB_KHR + +#ifdef VK_USE_PLATFORM_DIRECTFB_EXT +typedef struct { + VkIcdSurfaceBase base; + IDirectFB *dfb; + IDirectFBSurface *surface; +} VkIcdSurfaceDirectFB; +#endif // VK_USE_PLATFORM_DIRECTFB_EXT + +#ifdef VK_USE_PLATFORM_ANDROID_KHR +typedef struct { + VkIcdSurfaceBase base; + struct ANativeWindow *window; +} VkIcdSurfaceAndroid; +#endif // VK_USE_PLATFORM_ANDROID_KHR + +#ifdef VK_USE_PLATFORM_MACOS_MVK +typedef struct { + VkIcdSurfaceBase base; + const void *pView; +} VkIcdSurfaceMacOS; +#endif // VK_USE_PLATFORM_MACOS_MVK + +#ifdef VK_USE_PLATFORM_IOS_MVK +typedef struct { + VkIcdSurfaceBase base; + const void *pView; +} VkIcdSurfaceIOS; +#endif // VK_USE_PLATFORM_IOS_MVK + +#ifdef VK_USE_PLATFORM_GGP +typedef struct { + VkIcdSurfaceBase base; + GgpStreamDescriptor streamDescriptor; +} VkIcdSurfaceGgp; +#endif // VK_USE_PLATFORM_GGP + +typedef struct { + VkIcdSurfaceBase base; + VkDisplayModeKHR displayMode; + uint32_t planeIndex; + uint32_t planeStackIndex; + VkSurfaceTransformFlagBitsKHR transform; + float globalAlpha; + VkDisplayPlaneAlphaFlagBitsKHR alphaMode; + VkExtent2D imageExtent; +} VkIcdSurfaceDisplay; + +typedef struct { + VkIcdSurfaceBase base; +} VkIcdSurfaceHeadless; + +#ifdef VK_USE_PLATFORM_METAL_EXT +typedef struct { + VkIcdSurfaceBase base; + const CAMetalLayer *pLayer; +} VkIcdSurfaceMetal; +#endif // VK_USE_PLATFORM_METAL_EXT + +#ifdef VK_USE_PLATFORM_VI_NN +typedef struct { + VkIcdSurfaceBase base; + void *window; +} VkIcdSurfaceVi; +#endif // VK_USE_PLATFORM_VI_NN + +#ifdef VK_USE_PLATFORM_SCREEN_QNX +typedef struct { + VkIcdSurfaceBase base; + struct _screen_context *context; + struct _screen_window *window; +} VkIcdSurfaceScreen; +#endif // VK_USE_PLATFORM_SCREEN_QNX + +#ifdef VK_USE_PLATFORM_FUCHSIA +typedef struct { + VkIcdSurfaceBase base; +} VkIcdSurfaceImagePipe; +#endif // VK_USE_PLATFORM_FUCHSIA diff --git a/external/vulkan/vk_layer.h b/external/vulkan/vk_layer.h new file mode 100644 index 0000000..19d88fc --- /dev/null +++ b/external/vulkan/vk_layer.h @@ -0,0 +1,189 @@ +/* + * Copyright 2015-2023 The Khronos Group Inc. + * Copyright 2015-2023 Valve Corporation + * Copyright 2015-2023 LunarG, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +/* Need to define dispatch table + * Core struct can then have ptr to dispatch table at the top + * Along with object ptrs for current and next OBJ + */ + +#include "vulkan_core.h" + +#define MAX_NUM_UNKNOWN_EXTS 250 + + // Loader-Layer version negotiation API. Versions add the following features: + // Versions 0/1 - Initial. Doesn't support vk_layerGetPhysicalDeviceProcAddr + // or vk_icdNegotiateLoaderLayerInterfaceVersion. + // Version 2 - Add support for vk_layerGetPhysicalDeviceProcAddr and + // vk_icdNegotiateLoaderLayerInterfaceVersion. +#define CURRENT_LOADER_LAYER_INTERFACE_VERSION 2 +#define MIN_SUPPORTED_LOADER_LAYER_INTERFACE_VERSION 1 + +#define VK_CURRENT_CHAIN_VERSION 1 + +// Typedef for use in the interfaces below +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName); + +// Version negotiation values +typedef enum VkNegotiateLayerStructType { + LAYER_NEGOTIATE_UNINTIALIZED = 0, + LAYER_NEGOTIATE_INTERFACE_STRUCT = 1, +} VkNegotiateLayerStructType; + +// Version negotiation structures +typedef struct VkNegotiateLayerInterface { + VkNegotiateLayerStructType sType; + void *pNext; + uint32_t loaderLayerInterfaceVersion; + PFN_vkGetInstanceProcAddr pfnGetInstanceProcAddr; + PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr; + PFN_GetPhysicalDeviceProcAddr pfnGetPhysicalDeviceProcAddr; +} VkNegotiateLayerInterface; + +// Version negotiation functions +typedef VkResult (VKAPI_PTR *PFN_vkNegotiateLoaderLayerInterfaceVersion)(VkNegotiateLayerInterface *pVersionStruct); + +// Function prototype for unknown physical device extension command +typedef VkResult(VKAPI_PTR *PFN_PhysDevExt)(VkPhysicalDevice phys_device); + +// ------------------------------------------------------------------------------------------------ +// CreateInstance and CreateDevice support structures + +/* Sub type of structure for instance and device loader ext of CreateInfo. + * When sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO + * or sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO + * then VkLayerFunction indicates struct type pointed to by pNext + */ +typedef enum VkLayerFunction_ { + VK_LAYER_LINK_INFO = 0, + VK_LOADER_DATA_CALLBACK = 1, + VK_LOADER_LAYER_CREATE_DEVICE_CALLBACK = 2, + VK_LOADER_FEATURES = 3, +} VkLayerFunction; + +typedef struct VkLayerInstanceLink_ { + struct VkLayerInstanceLink_ *pNext; + PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr; + PFN_GetPhysicalDeviceProcAddr pfnNextGetPhysicalDeviceProcAddr; +} VkLayerInstanceLink; + +/* + * When creating the device chain the loader needs to pass + * down information about it's device structure needed at + * the end of the chain. Passing the data via the + * VkLayerDeviceInfo avoids issues with finding the + * exact instance being used. + */ +typedef struct VkLayerDeviceInfo_ { + void *device_info; + PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr; +} VkLayerDeviceInfo; + +typedef VkResult (VKAPI_PTR *PFN_vkSetInstanceLoaderData)(VkInstance instance, + void *object); +typedef VkResult (VKAPI_PTR *PFN_vkSetDeviceLoaderData)(VkDevice device, + void *object); +typedef VkResult (VKAPI_PTR *PFN_vkLayerCreateDevice)(VkInstance instance, VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, PFN_vkGetInstanceProcAddr layerGIPA, PFN_vkGetDeviceProcAddr *nextGDPA); +typedef void (VKAPI_PTR *PFN_vkLayerDestroyDevice)(VkDevice physicalDevice, const VkAllocationCallbacks *pAllocator, PFN_vkDestroyDevice destroyFunction); + +typedef enum VkLoaderFeastureFlagBits { + VK_LOADER_FEATURE_PHYSICAL_DEVICE_SORTING = 0x00000001, +} VkLoaderFlagBits; +typedef VkFlags VkLoaderFeatureFlags; + +typedef struct { + VkStructureType sType; // VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO + const void *pNext; + VkLayerFunction function; + union { + VkLayerInstanceLink *pLayerInfo; + PFN_vkSetInstanceLoaderData pfnSetInstanceLoaderData; + struct { + PFN_vkLayerCreateDevice pfnLayerCreateDevice; + PFN_vkLayerDestroyDevice pfnLayerDestroyDevice; + } layerDevice; + VkLoaderFeatureFlags loaderFeatures; + } u; +} VkLayerInstanceCreateInfo; + +typedef struct VkLayerDeviceLink_ { + struct VkLayerDeviceLink_ *pNext; + PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr; + PFN_vkGetDeviceProcAddr pfnNextGetDeviceProcAddr; +} VkLayerDeviceLink; + +typedef struct { + VkStructureType sType; // VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO + const void *pNext; + VkLayerFunction function; + union { + VkLayerDeviceLink *pLayerInfo; + PFN_vkSetDeviceLoaderData pfnSetDeviceLoaderData; + } u; +} VkLayerDeviceCreateInfo; + +#ifdef __cplusplus +extern "C" { +#endif + +VKAPI_ATTR VkResult VKAPI_CALL vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct); + +typedef enum VkChainType { + VK_CHAIN_TYPE_UNKNOWN = 0, + VK_CHAIN_TYPE_ENUMERATE_INSTANCE_EXTENSION_PROPERTIES = 1, + VK_CHAIN_TYPE_ENUMERATE_INSTANCE_LAYER_PROPERTIES = 2, + VK_CHAIN_TYPE_ENUMERATE_INSTANCE_VERSION = 3, +} VkChainType; + +typedef struct VkChainHeader { + VkChainType type; + uint32_t version; + uint32_t size; +} VkChainHeader; + +typedef struct VkEnumerateInstanceExtensionPropertiesChain { + VkChainHeader header; + VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceExtensionPropertiesChain *, const char *, uint32_t *, + VkExtensionProperties *); + const struct VkEnumerateInstanceExtensionPropertiesChain *pNextLink; + +#if defined(__cplusplus) + inline VkResult CallDown(const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) const { + return pfnNextLayer(pNextLink, pLayerName, pPropertyCount, pProperties); + } +#endif +} VkEnumerateInstanceExtensionPropertiesChain; + +typedef struct VkEnumerateInstanceLayerPropertiesChain { + VkChainHeader header; + VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceLayerPropertiesChain *, uint32_t *, VkLayerProperties *); + const struct VkEnumerateInstanceLayerPropertiesChain *pNextLink; + +#if defined(__cplusplus) + inline VkResult CallDown(uint32_t *pPropertyCount, VkLayerProperties *pProperties) const { + return pfnNextLayer(pNextLink, pPropertyCount, pProperties); + } +#endif +} VkEnumerateInstanceLayerPropertiesChain; + +typedef struct VkEnumerateInstanceVersionChain { + VkChainHeader header; + VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceVersionChain *, uint32_t *); + const struct VkEnumerateInstanceVersionChain *pNextLink; + +#if defined(__cplusplus) + inline VkResult CallDown(uint32_t *pApiVersion) const { + return pfnNextLayer(pNextLink, pApiVersion); + } +#endif +} VkEnumerateInstanceVersionChain; + +#ifdef __cplusplus +} +#endif diff --git a/external/vulkan/vk_platform.h b/external/vulkan/vk_platform.h index 3ff8c5d..0ecd4f6 100644 --- a/external/vulkan/vk_platform.h +++ b/external/vulkan/vk_platform.h @@ -2,7 +2,7 @@ // File: vk_platform.h // /* -** Copyright 2014-2022 The Khronos Group Inc. +** Copyright 2014-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ diff --git a/external/vulkan/vulkan.cppm b/external/vulkan/vulkan.cppm new file mode 100644 index 0000000..0b7fafb Binary files /dev/null and b/external/vulkan/vulkan.cppm differ diff --git a/external/vulkan/vulkan.h b/external/vulkan/vulkan.h index 3510ac9..ef94006 100644 --- a/external/vulkan/vulkan.h +++ b/external/vulkan/vulkan.h @@ -2,7 +2,7 @@ #define VULKAN_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -84,6 +84,14 @@ #include "vulkan_screen.h" #endif + +#ifdef VK_USE_PLATFORM_SCI +#include +#include +#include "vulkan_sci.h" +#endif + + #ifdef VK_ENABLE_BETA_EXTENSIONS #include "vulkan_beta.h" #endif diff --git a/external/vulkan/vulkan.hpp b/external/vulkan/vulkan.hpp new file mode 100644 index 0000000..f456a7a Binary files /dev/null and b/external/vulkan/vulkan.hpp differ diff --git a/external/vulkan/vulkan_android.h b/external/vulkan/vulkan_android.h index 11f5397..61ff40b 100644 --- a/external/vulkan/vulkan_android.h +++ b/external/vulkan/vulkan_android.h @@ -2,7 +2,7 @@ #define VULKAN_ANDROID_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ extern "C" { +// VK_KHR_android_surface is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_android_surface 1 struct ANativeWindow; #define VK_KHR_ANDROID_SURFACE_SPEC_VERSION 6 @@ -42,6 +43,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR( #endif +// VK_ANDROID_external_memory_android_hardware_buffer is a preprocessor guard. Do not pass it to API calls. #define VK_ANDROID_external_memory_android_hardware_buffer 1 struct AHardwareBuffer; #define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 5 @@ -118,6 +120,32 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryAndroidHardwareBufferANDROID( struct AHardwareBuffer** pBuffer); #endif + +// VK_ANDROID_external_format_resolve is a preprocessor guard. Do not pass it to API calls. +#define VK_ANDROID_external_format_resolve 1 +#define VK_ANDROID_EXTERNAL_FORMAT_RESOLVE_SPEC_VERSION 1 +#define VK_ANDROID_EXTERNAL_FORMAT_RESOLVE_EXTENSION_NAME "VK_ANDROID_external_format_resolve" +typedef struct VkPhysicalDeviceExternalFormatResolveFeaturesANDROID { + VkStructureType sType; + void* pNext; + VkBool32 externalFormatResolve; +} VkPhysicalDeviceExternalFormatResolveFeaturesANDROID; + +typedef struct VkPhysicalDeviceExternalFormatResolvePropertiesANDROID { + VkStructureType sType; + void* pNext; + VkBool32 nullColorAttachmentWithExternalFormatResolve; + VkChromaLocation externalFormatResolveChromaOffsetX; + VkChromaLocation externalFormatResolveChromaOffsetY; +} VkPhysicalDeviceExternalFormatResolvePropertiesANDROID; + +typedef struct VkAndroidHardwareBufferFormatResolvePropertiesANDROID { + VkStructureType sType; + void* pNext; + VkFormat colorAttachmentFormat; +} VkAndroidHardwareBufferFormatResolvePropertiesANDROID; + + #ifdef __cplusplus } #endif diff --git a/external/vulkan/vulkan_beta.h b/external/vulkan/vulkan_beta.h index cfeda0e..df18b40 100644 --- a/external/vulkan/vulkan_beta.h +++ b/external/vulkan/vulkan_beta.h @@ -2,7 +2,7 @@ #define VULKAN_BETA_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ extern "C" { +// VK_KHR_portability_subset is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_portability_subset 1 #define VK_KHR_PORTABILITY_SUBSET_SPEC_VERSION 1 #define VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME "VK_KHR_portability_subset" @@ -50,500 +51,162 @@ typedef struct VkPhysicalDevicePortabilitySubsetPropertiesKHR { -#define VK_KHR_video_encode_queue 1 -#define VK_KHR_VIDEO_ENCODE_QUEUE_SPEC_VERSION 7 -#define VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME "VK_KHR_video_encode_queue" - -typedef enum VkVideoEncodeTuningModeKHR { - VK_VIDEO_ENCODE_TUNING_MODE_DEFAULT_KHR = 0, - VK_VIDEO_ENCODE_TUNING_MODE_HIGH_QUALITY_KHR = 1, - VK_VIDEO_ENCODE_TUNING_MODE_LOW_LATENCY_KHR = 2, - VK_VIDEO_ENCODE_TUNING_MODE_ULTRA_LOW_LATENCY_KHR = 3, - VK_VIDEO_ENCODE_TUNING_MODE_LOSSLESS_KHR = 4, - VK_VIDEO_ENCODE_TUNING_MODE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkVideoEncodeTuningModeKHR; -typedef VkFlags VkVideoEncodeFlagsKHR; - -typedef enum VkVideoEncodeCapabilityFlagBitsKHR { - VK_VIDEO_ENCODE_CAPABILITY_PRECEDING_EXTERNALLY_ENCODED_BYTES_BIT_KHR = 0x00000001, - VK_VIDEO_ENCODE_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkVideoEncodeCapabilityFlagBitsKHR; -typedef VkFlags VkVideoEncodeCapabilityFlagsKHR; - -typedef enum VkVideoEncodeRateControlModeFlagBitsKHR { - VK_VIDEO_ENCODE_RATE_CONTROL_MODE_NONE_BIT_KHR = 0, - VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR = 1, - VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR = 2, - VK_VIDEO_ENCODE_RATE_CONTROL_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkVideoEncodeRateControlModeFlagBitsKHR; -typedef VkFlags VkVideoEncodeRateControlModeFlagsKHR; - -typedef enum VkVideoEncodeUsageFlagBitsKHR { - VK_VIDEO_ENCODE_USAGE_DEFAULT_KHR = 0, - VK_VIDEO_ENCODE_USAGE_TRANSCODING_BIT_KHR = 0x00000001, - VK_VIDEO_ENCODE_USAGE_STREAMING_BIT_KHR = 0x00000002, - VK_VIDEO_ENCODE_USAGE_RECORDING_BIT_KHR = 0x00000004, - VK_VIDEO_ENCODE_USAGE_CONFERENCING_BIT_KHR = 0x00000008, - VK_VIDEO_ENCODE_USAGE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkVideoEncodeUsageFlagBitsKHR; -typedef VkFlags VkVideoEncodeUsageFlagsKHR; - -typedef enum VkVideoEncodeContentFlagBitsKHR { - VK_VIDEO_ENCODE_CONTENT_DEFAULT_KHR = 0, - VK_VIDEO_ENCODE_CONTENT_CAMERA_BIT_KHR = 0x00000001, - VK_VIDEO_ENCODE_CONTENT_DESKTOP_BIT_KHR = 0x00000002, - VK_VIDEO_ENCODE_CONTENT_RENDERED_BIT_KHR = 0x00000004, - VK_VIDEO_ENCODE_CONTENT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkVideoEncodeContentFlagBitsKHR; -typedef VkFlags VkVideoEncodeContentFlagsKHR; -typedef VkFlags VkVideoEncodeRateControlFlagsKHR; -typedef struct VkVideoEncodeInfoKHR { - VkStructureType sType; - const void* pNext; - VkVideoEncodeFlagsKHR flags; - uint32_t qualityLevel; - VkBuffer dstBitstreamBuffer; - VkDeviceSize dstBitstreamBufferOffset; - VkDeviceSize dstBitstreamBufferMaxRange; - VkVideoPictureResourceInfoKHR srcPictureResource; - const VkVideoReferenceSlotInfoKHR* pSetupReferenceSlot; - uint32_t referenceSlotCount; - const VkVideoReferenceSlotInfoKHR* pReferenceSlots; - uint32_t precedingExternallyEncodedBytes; -} VkVideoEncodeInfoKHR; - -typedef struct VkVideoEncodeCapabilitiesKHR { - VkStructureType sType; - void* pNext; - VkVideoEncodeCapabilityFlagsKHR flags; - VkVideoEncodeRateControlModeFlagsKHR rateControlModes; - uint8_t rateControlLayerCount; - uint8_t qualityLevelCount; - VkExtent2D inputImageDataFillAlignment; -} VkVideoEncodeCapabilitiesKHR; - -typedef struct VkVideoEncodeUsageInfoKHR { - VkStructureType sType; - const void* pNext; - VkVideoEncodeUsageFlagsKHR videoUsageHints; - VkVideoEncodeContentFlagsKHR videoContentHints; - VkVideoEncodeTuningModeKHR tuningMode; -} VkVideoEncodeUsageInfoKHR; - -typedef struct VkVideoEncodeRateControlLayerInfoKHR { +// VK_AMDX_shader_enqueue is a preprocessor guard. Do not pass it to API calls. +#define VK_AMDX_shader_enqueue 1 +#define VK_AMDX_SHADER_ENQUEUE_SPEC_VERSION 1 +#define VK_AMDX_SHADER_ENQUEUE_EXTENSION_NAME "VK_AMDX_shader_enqueue" +#define VK_SHADER_INDEX_UNUSED_AMDX (~0U) +typedef struct VkPhysicalDeviceShaderEnqueueFeaturesAMDX { VkStructureType sType; - const void* pNext; - uint32_t averageBitrate; - uint32_t maxBitrate; - uint32_t frameRateNumerator; - uint32_t frameRateDenominator; - uint32_t virtualBufferSizeInMs; - uint32_t initialVirtualBufferSizeInMs; -} VkVideoEncodeRateControlLayerInfoKHR; + void* pNext; + VkBool32 shaderEnqueue; +} VkPhysicalDeviceShaderEnqueueFeaturesAMDX; -typedef struct VkVideoEncodeRateControlInfoKHR { - VkStructureType sType; - const void* pNext; - VkVideoEncodeRateControlFlagsKHR flags; - VkVideoEncodeRateControlModeFlagBitsKHR rateControlMode; - uint8_t layerCount; - const VkVideoEncodeRateControlLayerInfoKHR* pLayerConfigs; -} VkVideoEncodeRateControlInfoKHR; +typedef struct VkPhysicalDeviceShaderEnqueuePropertiesAMDX { + VkStructureType sType; + void* pNext; + uint32_t maxExecutionGraphDepth; + uint32_t maxExecutionGraphShaderOutputNodes; + uint32_t maxExecutionGraphShaderPayloadSize; + uint32_t maxExecutionGraphShaderPayloadCount; + uint32_t executionGraphDispatchAddressAlignment; +} VkPhysicalDeviceShaderEnqueuePropertiesAMDX; -typedef void (VKAPI_PTR *PFN_vkCmdEncodeVideoKHR)(VkCommandBuffer commandBuffer, const VkVideoEncodeInfoKHR* pEncodeInfo); +typedef struct VkExecutionGraphPipelineScratchSizeAMDX { + VkStructureType sType; + void* pNext; + VkDeviceSize size; +} VkExecutionGraphPipelineScratchSizeAMDX; + +typedef struct VkExecutionGraphPipelineCreateInfoAMDX { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; + const VkPipelineLibraryCreateInfoKHR* pLibraryInfo; + VkPipelineLayout layout; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkExecutionGraphPipelineCreateInfoAMDX; + +typedef union VkDeviceOrHostAddressConstAMDX { + VkDeviceAddress deviceAddress; + const void* hostAddress; +} VkDeviceOrHostAddressConstAMDX; + +typedef struct VkDispatchGraphInfoAMDX { + uint32_t nodeIndex; + uint32_t payloadCount; + VkDeviceOrHostAddressConstAMDX payloads; + uint64_t payloadStride; +} VkDispatchGraphInfoAMDX; + +typedef struct VkDispatchGraphCountInfoAMDX { + uint32_t count; + VkDeviceOrHostAddressConstAMDX infos; + uint64_t stride; +} VkDispatchGraphCountInfoAMDX; + +typedef struct VkPipelineShaderStageNodeCreateInfoAMDX { + VkStructureType sType; + const void* pNext; + const char* pName; + uint32_t index; +} VkPipelineShaderStageNodeCreateInfoAMDX; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateExecutionGraphPipelinesAMDX)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkExecutionGraphPipelineCreateInfoAMDX* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef VkResult (VKAPI_PTR *PFN_vkGetExecutionGraphPipelineScratchSizeAMDX)(VkDevice device, VkPipeline executionGraph, VkExecutionGraphPipelineScratchSizeAMDX* pSizeInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetExecutionGraphPipelineNodeIndexAMDX)(VkDevice device, VkPipeline executionGraph, const VkPipelineShaderStageNodeCreateInfoAMDX* pNodeInfo, uint32_t* pNodeIndex); +typedef void (VKAPI_PTR *PFN_vkCmdInitializeGraphScratchMemoryAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, const VkDispatchGraphCountInfoAMDX* pCountInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphIndirectAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, const VkDispatchGraphCountInfoAMDX* pCountInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphIndirectCountAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, VkDeviceAddress countInfo); #ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdEncodeVideoKHR( +VKAPI_ATTR VkResult VKAPI_CALL vkCreateExecutionGraphPipelinesAMDX( + VkDevice device, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkExecutionGraphPipelineCreateInfoAMDX* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetExecutionGraphPipelineScratchSizeAMDX( + VkDevice device, + VkPipeline executionGraph, + VkExecutionGraphPipelineScratchSizeAMDX* pSizeInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetExecutionGraphPipelineNodeIndexAMDX( + VkDevice device, + VkPipeline executionGraph, + const VkPipelineShaderStageNodeCreateInfoAMDX* pNodeInfo, + uint32_t* pNodeIndex); + +VKAPI_ATTR void VKAPI_CALL vkCmdInitializeGraphScratchMemoryAMDX( VkCommandBuffer commandBuffer, - const VkVideoEncodeInfoKHR* pEncodeInfo); + VkDeviceAddress scratch); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchGraphAMDX( + VkCommandBuffer commandBuffer, + VkDeviceAddress scratch, + const VkDispatchGraphCountInfoAMDX* pCountInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchGraphIndirectAMDX( + VkCommandBuffer commandBuffer, + VkDeviceAddress scratch, + const VkDispatchGraphCountInfoAMDX* pCountInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchGraphIndirectCountAMDX( + VkCommandBuffer commandBuffer, + VkDeviceAddress scratch, + VkDeviceAddress countInfo); #endif -#define VK_EXT_video_encode_h264 1 -#include "vk_video/vulkan_video_codec_h264std.h" -#include "vk_video/vulkan_video_codec_h264std_encode.h" -#define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 9 -#define VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME "VK_EXT_video_encode_h264" +// VK_NV_displacement_micromap is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_displacement_micromap 1 +#define VK_NV_DISPLACEMENT_MICROMAP_SPEC_VERSION 2 +#define VK_NV_DISPLACEMENT_MICROMAP_EXTENSION_NAME "VK_NV_displacement_micromap" -typedef enum VkVideoEncodeH264RateControlStructureEXT { - VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_UNKNOWN_EXT = 0, - VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_FLAT_EXT = 1, - VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_DYADIC_EXT = 2, - VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkVideoEncodeH264RateControlStructureEXT; - -typedef enum VkVideoEncodeH264CapabilityFlagBitsEXT { - VK_VIDEO_ENCODE_H264_CAPABILITY_DIRECT_8X8_INFERENCE_ENABLED_BIT_EXT = 0x00000001, - VK_VIDEO_ENCODE_H264_CAPABILITY_DIRECT_8X8_INFERENCE_DISABLED_BIT_EXT = 0x00000002, - VK_VIDEO_ENCODE_H264_CAPABILITY_SEPARATE_COLOUR_PLANE_BIT_EXT = 0x00000004, - VK_VIDEO_ENCODE_H264_CAPABILITY_QPPRIME_Y_ZERO_TRANSFORM_BYPASS_BIT_EXT = 0x00000008, - VK_VIDEO_ENCODE_H264_CAPABILITY_SCALING_LISTS_BIT_EXT = 0x00000010, - VK_VIDEO_ENCODE_H264_CAPABILITY_HRD_COMPLIANCE_BIT_EXT = 0x00000020, - VK_VIDEO_ENCODE_H264_CAPABILITY_CHROMA_QP_OFFSET_BIT_EXT = 0x00000040, - VK_VIDEO_ENCODE_H264_CAPABILITY_SECOND_CHROMA_QP_OFFSET_BIT_EXT = 0x00000080, - VK_VIDEO_ENCODE_H264_CAPABILITY_PIC_INIT_QP_MINUS26_BIT_EXT = 0x00000100, - VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_PRED_BIT_EXT = 0x00000200, - VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BIPRED_EXPLICIT_BIT_EXT = 0x00000400, - VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BIPRED_IMPLICIT_BIT_EXT = 0x00000800, - VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_PRED_NO_TABLE_BIT_EXT = 0x00001000, - VK_VIDEO_ENCODE_H264_CAPABILITY_TRANSFORM_8X8_BIT_EXT = 0x00002000, - VK_VIDEO_ENCODE_H264_CAPABILITY_CABAC_BIT_EXT = 0x00004000, - VK_VIDEO_ENCODE_H264_CAPABILITY_CAVLC_BIT_EXT = 0x00008000, - VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_DISABLED_BIT_EXT = 0x00010000, - VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_ENABLED_BIT_EXT = 0x00020000, - VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_PARTIAL_BIT_EXT = 0x00040000, - VK_VIDEO_ENCODE_H264_CAPABILITY_DISABLE_DIRECT_SPATIAL_MV_PRED_BIT_EXT = 0x00080000, - VK_VIDEO_ENCODE_H264_CAPABILITY_MULTIPLE_SLICE_PER_FRAME_BIT_EXT = 0x00100000, - VK_VIDEO_ENCODE_H264_CAPABILITY_SLICE_MB_COUNT_BIT_EXT = 0x00200000, - VK_VIDEO_ENCODE_H264_CAPABILITY_ROW_UNALIGNED_SLICE_BIT_EXT = 0x00400000, - VK_VIDEO_ENCODE_H264_CAPABILITY_DIFFERENT_SLICE_TYPE_BIT_EXT = 0x00800000, - VK_VIDEO_ENCODE_H264_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_EXT = 0x01000000, - VK_VIDEO_ENCODE_H264_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkVideoEncodeH264CapabilityFlagBitsEXT; -typedef VkFlags VkVideoEncodeH264CapabilityFlagsEXT; - -typedef enum VkVideoEncodeH264InputModeFlagBitsEXT { - VK_VIDEO_ENCODE_H264_INPUT_MODE_FRAME_BIT_EXT = 0x00000001, - VK_VIDEO_ENCODE_H264_INPUT_MODE_SLICE_BIT_EXT = 0x00000002, - VK_VIDEO_ENCODE_H264_INPUT_MODE_NON_VCL_BIT_EXT = 0x00000004, - VK_VIDEO_ENCODE_H264_INPUT_MODE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkVideoEncodeH264InputModeFlagBitsEXT; -typedef VkFlags VkVideoEncodeH264InputModeFlagsEXT; - -typedef enum VkVideoEncodeH264OutputModeFlagBitsEXT { - VK_VIDEO_ENCODE_H264_OUTPUT_MODE_FRAME_BIT_EXT = 0x00000001, - VK_VIDEO_ENCODE_H264_OUTPUT_MODE_SLICE_BIT_EXT = 0x00000002, - VK_VIDEO_ENCODE_H264_OUTPUT_MODE_NON_VCL_BIT_EXT = 0x00000004, - VK_VIDEO_ENCODE_H264_OUTPUT_MODE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkVideoEncodeH264OutputModeFlagBitsEXT; -typedef VkFlags VkVideoEncodeH264OutputModeFlagsEXT; -typedef struct VkVideoEncodeH264CapabilitiesEXT { - VkStructureType sType; - void* pNext; - VkVideoEncodeH264CapabilityFlagsEXT flags; - VkVideoEncodeH264InputModeFlagsEXT inputModeFlags; - VkVideoEncodeH264OutputModeFlagsEXT outputModeFlags; - uint8_t maxPPictureL0ReferenceCount; - uint8_t maxBPictureL0ReferenceCount; - uint8_t maxL1ReferenceCount; - VkBool32 motionVectorsOverPicBoundariesFlag; - uint32_t maxBytesPerPicDenom; - uint32_t maxBitsPerMbDenom; - uint32_t log2MaxMvLengthHorizontal; - uint32_t log2MaxMvLengthVertical; -} VkVideoEncodeH264CapabilitiesEXT; - -typedef struct VkVideoEncodeH264SessionParametersAddInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t stdSPSCount; - const StdVideoH264SequenceParameterSet* pStdSPSs; - uint32_t stdPPSCount; - const StdVideoH264PictureParameterSet* pStdPPSs; -} VkVideoEncodeH264SessionParametersAddInfoEXT; - -typedef struct VkVideoEncodeH264SessionParametersCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t maxStdSPSCount; - uint32_t maxStdPPSCount; - const VkVideoEncodeH264SessionParametersAddInfoEXT* pParametersAddInfo; -} VkVideoEncodeH264SessionParametersCreateInfoEXT; - -typedef struct VkVideoEncodeH264DpbSlotInfoEXT { - VkStructureType sType; - const void* pNext; - int8_t slotIndex; - const StdVideoEncodeH264ReferenceInfo* pStdReferenceInfo; -} VkVideoEncodeH264DpbSlotInfoEXT; - -typedef struct VkVideoEncodeH264ReferenceListsInfoEXT { - VkStructureType sType; - const void* pNext; - uint8_t referenceList0EntryCount; - const VkVideoEncodeH264DpbSlotInfoEXT* pReferenceList0Entries; - uint8_t referenceList1EntryCount; - const VkVideoEncodeH264DpbSlotInfoEXT* pReferenceList1Entries; - const StdVideoEncodeH264RefMemMgmtCtrlOperations* pMemMgmtCtrlOperations; -} VkVideoEncodeH264ReferenceListsInfoEXT; - -typedef struct VkVideoEncodeH264NaluSliceInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t mbCount; - const VkVideoEncodeH264ReferenceListsInfoEXT* pReferenceFinalLists; - const StdVideoEncodeH264SliceHeader* pSliceHeaderStd; -} VkVideoEncodeH264NaluSliceInfoEXT; - -typedef struct VkVideoEncodeH264VclFrameInfoEXT { - VkStructureType sType; - const void* pNext; - const VkVideoEncodeH264ReferenceListsInfoEXT* pReferenceFinalLists; - uint32_t naluSliceEntryCount; - const VkVideoEncodeH264NaluSliceInfoEXT* pNaluSliceEntries; - const StdVideoEncodeH264PictureInfo* pCurrentPictureInfo; -} VkVideoEncodeH264VclFrameInfoEXT; - -typedef struct VkVideoEncodeH264EmitPictureParametersInfoEXT { +typedef enum VkDisplacementMicromapFormatNV { + VK_DISPLACEMENT_MICROMAP_FORMAT_64_TRIANGLES_64_BYTES_NV = 1, + VK_DISPLACEMENT_MICROMAP_FORMAT_256_TRIANGLES_128_BYTES_NV = 2, + VK_DISPLACEMENT_MICROMAP_FORMAT_1024_TRIANGLES_128_BYTES_NV = 3, + VK_DISPLACEMENT_MICROMAP_FORMAT_MAX_ENUM_NV = 0x7FFFFFFF +} VkDisplacementMicromapFormatNV; +typedef struct VkPhysicalDeviceDisplacementMicromapFeaturesNV { VkStructureType sType; - const void* pNext; - uint8_t spsId; - VkBool32 emitSpsEnable; - uint32_t ppsIdEntryCount; - const uint8_t* ppsIdEntries; -} VkVideoEncodeH264EmitPictureParametersInfoEXT; + void* pNext; + VkBool32 displacementMicromap; +} VkPhysicalDeviceDisplacementMicromapFeaturesNV; -typedef struct VkVideoEncodeH264ProfileInfoEXT { - VkStructureType sType; - const void* pNext; - StdVideoH264ProfileIdc stdProfileIdc; -} VkVideoEncodeH264ProfileInfoEXT; - -typedef struct VkVideoEncodeH264RateControlInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t gopFrameCount; - uint32_t idrPeriod; - uint32_t consecutiveBFrameCount; - VkVideoEncodeH264RateControlStructureEXT rateControlStructure; - uint8_t temporalLayerCount; -} VkVideoEncodeH264RateControlInfoEXT; - -typedef struct VkVideoEncodeH264QpEXT { - int32_t qpI; - int32_t qpP; - int32_t qpB; -} VkVideoEncodeH264QpEXT; - -typedef struct VkVideoEncodeH264FrameSizeEXT { - uint32_t frameISize; - uint32_t framePSize; - uint32_t frameBSize; -} VkVideoEncodeH264FrameSizeEXT; - -typedef struct VkVideoEncodeH264RateControlLayerInfoEXT { - VkStructureType sType; - const void* pNext; - uint8_t temporalLayerId; - VkBool32 useInitialRcQp; - VkVideoEncodeH264QpEXT initialRcQp; - VkBool32 useMinQp; - VkVideoEncodeH264QpEXT minQp; - VkBool32 useMaxQp; - VkVideoEncodeH264QpEXT maxQp; - VkBool32 useMaxFrameSize; - VkVideoEncodeH264FrameSizeEXT maxFrameSize; -} VkVideoEncodeH264RateControlLayerInfoEXT; - - - -#define VK_EXT_video_encode_h265 1 -#include "vk_video/vulkan_video_codec_h265std.h" -#include "vk_video/vulkan_video_codec_h265std_encode.h" -#define VK_EXT_VIDEO_ENCODE_H265_SPEC_VERSION 9 -#define VK_EXT_VIDEO_ENCODE_H265_EXTENSION_NAME "VK_EXT_video_encode_h265" - -typedef enum VkVideoEncodeH265RateControlStructureEXT { - VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_UNKNOWN_EXT = 0, - VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_FLAT_EXT = 1, - VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_DYADIC_EXT = 2, - VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkVideoEncodeH265RateControlStructureEXT; - -typedef enum VkVideoEncodeH265CapabilityFlagBitsEXT { - VK_VIDEO_ENCODE_H265_CAPABILITY_SEPARATE_COLOUR_PLANE_BIT_EXT = 0x00000001, - VK_VIDEO_ENCODE_H265_CAPABILITY_SCALING_LISTS_BIT_EXT = 0x00000002, - VK_VIDEO_ENCODE_H265_CAPABILITY_SAMPLE_ADAPTIVE_OFFSET_ENABLED_BIT_EXT = 0x00000004, - VK_VIDEO_ENCODE_H265_CAPABILITY_PCM_ENABLE_BIT_EXT = 0x00000008, - VK_VIDEO_ENCODE_H265_CAPABILITY_SPS_TEMPORAL_MVP_ENABLED_BIT_EXT = 0x00000010, - VK_VIDEO_ENCODE_H265_CAPABILITY_HRD_COMPLIANCE_BIT_EXT = 0x00000020, - VK_VIDEO_ENCODE_H265_CAPABILITY_INIT_QP_MINUS26_BIT_EXT = 0x00000040, - VK_VIDEO_ENCODE_H265_CAPABILITY_LOG2_PARALLEL_MERGE_LEVEL_MINUS2_BIT_EXT = 0x00000080, - VK_VIDEO_ENCODE_H265_CAPABILITY_SIGN_DATA_HIDING_ENABLED_BIT_EXT = 0x00000100, - VK_VIDEO_ENCODE_H265_CAPABILITY_TRANSFORM_SKIP_ENABLED_BIT_EXT = 0x00000200, - VK_VIDEO_ENCODE_H265_CAPABILITY_TRANSFORM_SKIP_DISABLED_BIT_EXT = 0x00000400, - VK_VIDEO_ENCODE_H265_CAPABILITY_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT_BIT_EXT = 0x00000800, - VK_VIDEO_ENCODE_H265_CAPABILITY_WEIGHTED_PRED_BIT_EXT = 0x00001000, - VK_VIDEO_ENCODE_H265_CAPABILITY_WEIGHTED_BIPRED_BIT_EXT = 0x00002000, - VK_VIDEO_ENCODE_H265_CAPABILITY_WEIGHTED_PRED_NO_TABLE_BIT_EXT = 0x00004000, - VK_VIDEO_ENCODE_H265_CAPABILITY_TRANSQUANT_BYPASS_ENABLED_BIT_EXT = 0x00008000, - VK_VIDEO_ENCODE_H265_CAPABILITY_ENTROPY_CODING_SYNC_ENABLED_BIT_EXT = 0x00010000, - VK_VIDEO_ENCODE_H265_CAPABILITY_DEBLOCKING_FILTER_OVERRIDE_ENABLED_BIT_EXT = 0x00020000, - VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_TILE_PER_FRAME_BIT_EXT = 0x00040000, - VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_SLICE_PER_TILE_BIT_EXT = 0x00080000, - VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_TILE_PER_SLICE_BIT_EXT = 0x00100000, - VK_VIDEO_ENCODE_H265_CAPABILITY_SLICE_SEGMENT_CTB_COUNT_BIT_EXT = 0x00200000, - VK_VIDEO_ENCODE_H265_CAPABILITY_ROW_UNALIGNED_SLICE_SEGMENT_BIT_EXT = 0x00400000, - VK_VIDEO_ENCODE_H265_CAPABILITY_DEPENDENT_SLICE_SEGMENT_BIT_EXT = 0x00800000, - VK_VIDEO_ENCODE_H265_CAPABILITY_DIFFERENT_SLICE_TYPE_BIT_EXT = 0x01000000, - VK_VIDEO_ENCODE_H265_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_EXT = 0x02000000, - VK_VIDEO_ENCODE_H265_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkVideoEncodeH265CapabilityFlagBitsEXT; -typedef VkFlags VkVideoEncodeH265CapabilityFlagsEXT; - -typedef enum VkVideoEncodeH265InputModeFlagBitsEXT { - VK_VIDEO_ENCODE_H265_INPUT_MODE_FRAME_BIT_EXT = 0x00000001, - VK_VIDEO_ENCODE_H265_INPUT_MODE_SLICE_SEGMENT_BIT_EXT = 0x00000002, - VK_VIDEO_ENCODE_H265_INPUT_MODE_NON_VCL_BIT_EXT = 0x00000004, - VK_VIDEO_ENCODE_H265_INPUT_MODE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkVideoEncodeH265InputModeFlagBitsEXT; -typedef VkFlags VkVideoEncodeH265InputModeFlagsEXT; - -typedef enum VkVideoEncodeH265OutputModeFlagBitsEXT { - VK_VIDEO_ENCODE_H265_OUTPUT_MODE_FRAME_BIT_EXT = 0x00000001, - VK_VIDEO_ENCODE_H265_OUTPUT_MODE_SLICE_SEGMENT_BIT_EXT = 0x00000002, - VK_VIDEO_ENCODE_H265_OUTPUT_MODE_NON_VCL_BIT_EXT = 0x00000004, - VK_VIDEO_ENCODE_H265_OUTPUT_MODE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkVideoEncodeH265OutputModeFlagBitsEXT; -typedef VkFlags VkVideoEncodeH265OutputModeFlagsEXT; - -typedef enum VkVideoEncodeH265CtbSizeFlagBitsEXT { - VK_VIDEO_ENCODE_H265_CTB_SIZE_16_BIT_EXT = 0x00000001, - VK_VIDEO_ENCODE_H265_CTB_SIZE_32_BIT_EXT = 0x00000002, - VK_VIDEO_ENCODE_H265_CTB_SIZE_64_BIT_EXT = 0x00000004, - VK_VIDEO_ENCODE_H265_CTB_SIZE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkVideoEncodeH265CtbSizeFlagBitsEXT; -typedef VkFlags VkVideoEncodeH265CtbSizeFlagsEXT; - -typedef enum VkVideoEncodeH265TransformBlockSizeFlagBitsEXT { - VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_4_BIT_EXT = 0x00000001, - VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_8_BIT_EXT = 0x00000002, - VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_16_BIT_EXT = 0x00000004, - VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_32_BIT_EXT = 0x00000008, - VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkVideoEncodeH265TransformBlockSizeFlagBitsEXT; -typedef VkFlags VkVideoEncodeH265TransformBlockSizeFlagsEXT; -typedef struct VkVideoEncodeH265CapabilitiesEXT { - VkStructureType sType; - void* pNext; - VkVideoEncodeH265CapabilityFlagsEXT flags; - VkVideoEncodeH265InputModeFlagsEXT inputModeFlags; - VkVideoEncodeH265OutputModeFlagsEXT outputModeFlags; - VkVideoEncodeH265CtbSizeFlagsEXT ctbSizes; - VkVideoEncodeH265TransformBlockSizeFlagsEXT transformBlockSizes; - uint8_t maxPPictureL0ReferenceCount; - uint8_t maxBPictureL0ReferenceCount; - uint8_t maxL1ReferenceCount; - uint8_t maxSubLayersCount; - uint8_t minLog2MinLumaCodingBlockSizeMinus3; - uint8_t maxLog2MinLumaCodingBlockSizeMinus3; - uint8_t minLog2MinLumaTransformBlockSizeMinus2; - uint8_t maxLog2MinLumaTransformBlockSizeMinus2; - uint8_t minMaxTransformHierarchyDepthInter; - uint8_t maxMaxTransformHierarchyDepthInter; - uint8_t minMaxTransformHierarchyDepthIntra; - uint8_t maxMaxTransformHierarchyDepthIntra; - uint8_t maxDiffCuQpDeltaDepth; - uint8_t minMaxNumMergeCand; - uint8_t maxMaxNumMergeCand; -} VkVideoEncodeH265CapabilitiesEXT; - -typedef struct VkVideoEncodeH265SessionParametersAddInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t stdVPSCount; - const StdVideoH265VideoParameterSet* pStdVPSs; - uint32_t stdSPSCount; - const StdVideoH265SequenceParameterSet* pStdSPSs; - uint32_t stdPPSCount; - const StdVideoH265PictureParameterSet* pStdPPSs; -} VkVideoEncodeH265SessionParametersAddInfoEXT; - -typedef struct VkVideoEncodeH265SessionParametersCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t maxStdVPSCount; - uint32_t maxStdSPSCount; - uint32_t maxStdPPSCount; - const VkVideoEncodeH265SessionParametersAddInfoEXT* pParametersAddInfo; -} VkVideoEncodeH265SessionParametersCreateInfoEXT; - -typedef struct VkVideoEncodeH265DpbSlotInfoEXT { - VkStructureType sType; - const void* pNext; - int8_t slotIndex; - const StdVideoEncodeH265ReferenceInfo* pStdReferenceInfo; -} VkVideoEncodeH265DpbSlotInfoEXT; - -typedef struct VkVideoEncodeH265ReferenceListsInfoEXT { - VkStructureType sType; - const void* pNext; - uint8_t referenceList0EntryCount; - const VkVideoEncodeH265DpbSlotInfoEXT* pReferenceList0Entries; - uint8_t referenceList1EntryCount; - const VkVideoEncodeH265DpbSlotInfoEXT* pReferenceList1Entries; - const StdVideoEncodeH265ReferenceModifications* pReferenceModifications; -} VkVideoEncodeH265ReferenceListsInfoEXT; - -typedef struct VkVideoEncodeH265NaluSliceSegmentInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t ctbCount; - const VkVideoEncodeH265ReferenceListsInfoEXT* pReferenceFinalLists; - const StdVideoEncodeH265SliceSegmentHeader* pSliceSegmentHeaderStd; -} VkVideoEncodeH265NaluSliceSegmentInfoEXT; - -typedef struct VkVideoEncodeH265VclFrameInfoEXT { - VkStructureType sType; - const void* pNext; - const VkVideoEncodeH265ReferenceListsInfoEXT* pReferenceFinalLists; - uint32_t naluSliceSegmentEntryCount; - const VkVideoEncodeH265NaluSliceSegmentInfoEXT* pNaluSliceSegmentEntries; - const StdVideoEncodeH265PictureInfo* pCurrentPictureInfo; -} VkVideoEncodeH265VclFrameInfoEXT; - -typedef struct VkVideoEncodeH265EmitPictureParametersInfoEXT { +typedef struct VkPhysicalDeviceDisplacementMicromapPropertiesNV { VkStructureType sType; - const void* pNext; - uint8_t vpsId; - uint8_t spsId; - VkBool32 emitVpsEnable; - VkBool32 emitSpsEnable; - uint32_t ppsIdEntryCount; - const uint8_t* ppsIdEntries; -} VkVideoEncodeH265EmitPictureParametersInfoEXT; + void* pNext; + uint32_t maxDisplacementMicromapSubdivisionLevel; +} VkPhysicalDeviceDisplacementMicromapPropertiesNV; -typedef struct VkVideoEncodeH265ProfileInfoEXT { - VkStructureType sType; - const void* pNext; - StdVideoH265ProfileIdc stdProfileIdc; -} VkVideoEncodeH265ProfileInfoEXT; - -typedef struct VkVideoEncodeH265RateControlInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t gopFrameCount; - uint32_t idrPeriod; - uint32_t consecutiveBFrameCount; - VkVideoEncodeH265RateControlStructureEXT rateControlStructure; - uint8_t subLayerCount; -} VkVideoEncodeH265RateControlInfoEXT; - -typedef struct VkVideoEncodeH265QpEXT { - int32_t qpI; - int32_t qpP; - int32_t qpB; -} VkVideoEncodeH265QpEXT; - -typedef struct VkVideoEncodeH265FrameSizeEXT { - uint32_t frameISize; - uint32_t framePSize; - uint32_t frameBSize; -} VkVideoEncodeH265FrameSizeEXT; - -typedef struct VkVideoEncodeH265RateControlLayerInfoEXT { - VkStructureType sType; - const void* pNext; - uint8_t temporalId; - VkBool32 useInitialRcQp; - VkVideoEncodeH265QpEXT initialRcQp; - VkBool32 useMinQp; - VkVideoEncodeH265QpEXT minQp; - VkBool32 useMaxQp; - VkVideoEncodeH265QpEXT maxQp; - VkBool32 useMaxFrameSize; - VkVideoEncodeH265FrameSizeEXT maxFrameSize; -} VkVideoEncodeH265RateControlLayerInfoEXT; +typedef struct VkAccelerationStructureTrianglesDisplacementMicromapNV { + VkStructureType sType; + void* pNext; + VkFormat displacementBiasAndScaleFormat; + VkFormat displacementVectorFormat; + VkDeviceOrHostAddressConstKHR displacementBiasAndScaleBuffer; + VkDeviceSize displacementBiasAndScaleStride; + VkDeviceOrHostAddressConstKHR displacementVectorBuffer; + VkDeviceSize displacementVectorStride; + VkDeviceOrHostAddressConstKHR displacedMicromapPrimitiveFlags; + VkDeviceSize displacedMicromapPrimitiveFlagsStride; + VkIndexType indexType; + VkDeviceOrHostAddressConstKHR indexBuffer; + VkDeviceSize indexStride; + uint32_t baseTriangle; + uint32_t usageCountsCount; + const VkMicromapUsageEXT* pUsageCounts; + const VkMicromapUsageEXT* const* ppUsageCounts; + VkMicromapEXT micromap; +} VkAccelerationStructureTrianglesDisplacementMicromapNV; #ifdef __cplusplus diff --git a/external/vulkan/vulkan_core.h b/external/vulkan/vulkan_core.h index e8fe548..1f30669 100644 Binary files a/external/vulkan/vulkan_core.h and b/external/vulkan/vulkan_core.h differ diff --git a/external/vulkan/vulkan_directfb.h b/external/vulkan/vulkan_directfb.h index ab3504e..f06f80b 100644 --- a/external/vulkan/vulkan_directfb.h +++ b/external/vulkan/vulkan_directfb.h @@ -2,7 +2,7 @@ #define VULKAN_DIRECTFB_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ extern "C" { +// VK_EXT_directfb_surface is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_directfb_surface 1 #define VK_EXT_DIRECTFB_SURFACE_SPEC_VERSION 1 #define VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME "VK_EXT_directfb_surface" diff --git a/external/vulkan/vulkan_enums.hpp b/external/vulkan/vulkan_enums.hpp new file mode 100644 index 0000000..222a796 Binary files /dev/null and b/external/vulkan/vulkan_enums.hpp differ diff --git a/external/vulkan/vulkan_extension_inspection.hpp b/external/vulkan/vulkan_extension_inspection.hpp new file mode 100644 index 0000000..d9df2f6 --- /dev/null +++ b/external/vulkan/vulkan_extension_inspection.hpp @@ -0,0 +1,3183 @@ +// Copyright 2015-2024 The Khronos Group Inc. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT +// + +// This header is generated from the Khronos Vulkan XML API Registry. + +#ifndef VULKAN_EXTENSION_INSPECTION_HPP +#define VULKAN_EXTENSION_INSPECTION_HPP + +#include +#include +#include +#include +#include + +namespace VULKAN_HPP_NAMESPACE +{ + //====================================== + //=== Extension inspection functions === + //====================================== + + std::set const & getDeviceExtensions(); + std::set const & getInstanceExtensions(); + std::map const & getDeprecatedExtensions(); + std::map>> const & getExtensionDepends( std::string const & extension ); + std::pair> const &> getExtensionDepends( std::string const & version, std::string const & extension ); + std::map const & getObsoletedExtensions(); + std::map const & getPromotedExtensions(); + VULKAN_HPP_CONSTEXPR_20 std::string getExtensionDeprecatedBy( std::string const & extension ); + VULKAN_HPP_CONSTEXPR_20 std::string getExtensionObsoletedBy( std::string const & extension ); + VULKAN_HPP_CONSTEXPR_20 std::string getExtensionPromotedTo( std::string const & extension ); + VULKAN_HPP_CONSTEXPR_20 bool isDeprecatedExtension( std::string const & extension ); + VULKAN_HPP_CONSTEXPR_20 bool isDeviceExtension( std::string const & extension ); + VULKAN_HPP_CONSTEXPR_20 bool isInstanceExtension( std::string const & extension ); + VULKAN_HPP_CONSTEXPR_20 bool isObsoletedExtension( std::string const & extension ); + VULKAN_HPP_CONSTEXPR_20 bool isPromotedExtension( std::string const & extension ); + + //===================================================== + //=== Extension inspection function implementations === + //===================================================== + + VULKAN_HPP_INLINE std::map const & getDeprecatedExtensions() + { + static std::map deprecatedExtensions = { + { "VK_EXT_debug_report", "VK_EXT_debug_utils" }, + { "VK_NV_glsl_shader", "" }, + { "VK_NV_dedicated_allocation", "VK_KHR_dedicated_allocation" }, + { "VK_AMD_gpu_shader_half_float", "VK_KHR_shader_float16_int8" }, + { "VK_IMG_format_pvrtc", "" }, + { "VK_NV_external_memory_capabilities", "VK_KHR_external_memory_capabilities" }, + { "VK_NV_external_memory", "VK_KHR_external_memory" }, +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + { "VK_NV_external_memory_win32", "VK_KHR_external_memory_win32" }, +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + { "VK_EXT_validation_flags", "VK_EXT_layer_settings" }, + { "VK_EXT_shader_subgroup_ballot", "VK_VERSION_1_2" }, + { "VK_EXT_shader_subgroup_vote", "VK_VERSION_1_1" }, +#if defined( VK_USE_PLATFORM_IOS_MVK ) + { "VK_MVK_ios_surface", "VK_EXT_metal_surface" }, +#endif /*VK_USE_PLATFORM_IOS_MVK*/ +#if defined( VK_USE_PLATFORM_MACOS_MVK ) + { "VK_MVK_macos_surface", "VK_EXT_metal_surface" }, +#endif /*VK_USE_PLATFORM_MACOS_MVK*/ + { "VK_AMD_gpu_shader_int16", "VK_KHR_shader_float16_int8" }, + { "VK_EXT_buffer_device_address", "VK_KHR_buffer_device_address" }, + { "VK_EXT_validation_features", "VK_EXT_layer_settings" } + }; + return deprecatedExtensions; + } + + VULKAN_HPP_INLINE std::set const & getDeviceExtensions() + { + static std::set deviceExtensions = { + "VK_KHR_swapchain", + "VK_KHR_display_swapchain", + "VK_NV_glsl_shader", + "VK_EXT_depth_range_unrestricted", + "VK_KHR_sampler_mirror_clamp_to_edge", + "VK_IMG_filter_cubic", + "VK_AMD_rasterization_order", + "VK_AMD_shader_trinary_minmax", + "VK_AMD_shader_explicit_vertex_parameter", + "VK_EXT_debug_marker", + "VK_KHR_video_queue", + "VK_KHR_video_decode_queue", + "VK_AMD_gcn_shader", + "VK_NV_dedicated_allocation", + "VK_EXT_transform_feedback", + "VK_NVX_binary_import", + "VK_NVX_image_view_handle", + "VK_AMD_draw_indirect_count", + "VK_AMD_negative_viewport_height", + "VK_AMD_gpu_shader_half_float", + "VK_AMD_shader_ballot", + "VK_KHR_video_encode_h264", + "VK_KHR_video_encode_h265", + "VK_KHR_video_decode_h264", + "VK_AMD_texture_gather_bias_lod", + "VK_AMD_shader_info", + "VK_KHR_dynamic_rendering", + "VK_AMD_shader_image_load_store_lod", + "VK_NV_corner_sampled_image", + "VK_KHR_multiview", + "VK_IMG_format_pvrtc", + "VK_NV_external_memory", +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + "VK_NV_external_memory_win32", + "VK_NV_win32_keyed_mutex", +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + "VK_KHR_device_group", + "VK_KHR_shader_draw_parameters", + "VK_EXT_shader_subgroup_ballot", + "VK_EXT_shader_subgroup_vote", + "VK_EXT_texture_compression_astc_hdr", + "VK_EXT_astc_decode_mode", + "VK_EXT_pipeline_robustness", + "VK_KHR_maintenance1", + "VK_KHR_external_memory", +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + "VK_KHR_external_memory_win32", +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + "VK_KHR_external_memory_fd", +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + "VK_KHR_win32_keyed_mutex", +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + "VK_KHR_external_semaphore", +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + "VK_KHR_external_semaphore_win32", +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + "VK_KHR_external_semaphore_fd", + "VK_KHR_push_descriptor", + "VK_EXT_conditional_rendering", + "VK_KHR_shader_float16_int8", + "VK_KHR_16bit_storage", + "VK_KHR_incremental_present", + "VK_KHR_descriptor_update_template", + "VK_NV_clip_space_w_scaling", + "VK_EXT_display_control", + "VK_GOOGLE_display_timing", + "VK_NV_sample_mask_override_coverage", + "VK_NV_geometry_shader_passthrough", + "VK_NV_viewport_array2", + "VK_NVX_multiview_per_view_attributes", + "VK_NV_viewport_swizzle", + "VK_EXT_discard_rectangles", + "VK_EXT_conservative_rasterization", + "VK_EXT_depth_clip_enable", + "VK_EXT_hdr_metadata", + "VK_KHR_imageless_framebuffer", + "VK_KHR_create_renderpass2", + "VK_IMG_relaxed_line_rasterization", + "VK_KHR_shared_presentable_image", + "VK_KHR_external_fence", +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + "VK_KHR_external_fence_win32", +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + "VK_KHR_external_fence_fd", + "VK_KHR_performance_query", + "VK_KHR_maintenance2", + "VK_KHR_variable_pointers", + "VK_EXT_external_memory_dma_buf", + "VK_EXT_queue_family_foreign", + "VK_KHR_dedicated_allocation", +#if defined( VK_USE_PLATFORM_ANDROID_KHR ) + "VK_ANDROID_external_memory_android_hardware_buffer", +#endif /*VK_USE_PLATFORM_ANDROID_KHR*/ + "VK_EXT_sampler_filter_minmax", + "VK_KHR_storage_buffer_storage_class", + "VK_AMD_gpu_shader_int16", +#if defined( VK_ENABLE_BETA_EXTENSIONS ) + "VK_AMDX_shader_enqueue", +#endif /*VK_ENABLE_BETA_EXTENSIONS*/ + "VK_AMD_mixed_attachment_samples", + "VK_AMD_shader_fragment_mask", + "VK_EXT_inline_uniform_block", + "VK_EXT_shader_stencil_export", + "VK_EXT_sample_locations", + "VK_KHR_relaxed_block_layout", + "VK_KHR_get_memory_requirements2", + "VK_KHR_image_format_list", + "VK_EXT_blend_operation_advanced", + "VK_NV_fragment_coverage_to_color", + "VK_KHR_acceleration_structure", + "VK_KHR_ray_tracing_pipeline", + "VK_KHR_ray_query", + "VK_NV_framebuffer_mixed_samples", + "VK_NV_fill_rectangle", + "VK_NV_shader_sm_builtins", + "VK_EXT_post_depth_coverage", + "VK_KHR_sampler_ycbcr_conversion", + "VK_KHR_bind_memory2", + "VK_EXT_image_drm_format_modifier", + "VK_EXT_validation_cache", + "VK_EXT_descriptor_indexing", + "VK_EXT_shader_viewport_index_layer", +#if defined( VK_ENABLE_BETA_EXTENSIONS ) + "VK_KHR_portability_subset", +#endif /*VK_ENABLE_BETA_EXTENSIONS*/ + "VK_NV_shading_rate_image", + "VK_NV_ray_tracing", + "VK_NV_representative_fragment_test", + "VK_KHR_maintenance3", + "VK_KHR_draw_indirect_count", + "VK_EXT_filter_cubic", + "VK_QCOM_render_pass_shader_resolve", + "VK_EXT_global_priority", + "VK_KHR_shader_subgroup_extended_types", + "VK_KHR_8bit_storage", + "VK_EXT_external_memory_host", + "VK_AMD_buffer_marker", + "VK_KHR_shader_atomic_int64", + "VK_KHR_shader_clock", + "VK_AMD_pipeline_compiler_control", + "VK_EXT_calibrated_timestamps", + "VK_AMD_shader_core_properties", + "VK_KHR_video_decode_h265", + "VK_KHR_global_priority", + "VK_AMD_memory_overallocation_behavior", + "VK_EXT_vertex_attribute_divisor", +#if defined( VK_USE_PLATFORM_GGP ) + "VK_GGP_frame_token", +#endif /*VK_USE_PLATFORM_GGP*/ + "VK_EXT_pipeline_creation_feedback", + "VK_KHR_driver_properties", + "VK_KHR_shader_float_controls", + "VK_NV_shader_subgroup_partitioned", + "VK_KHR_depth_stencil_resolve", + "VK_KHR_swapchain_mutable_format", + "VK_NV_compute_shader_derivatives", + "VK_NV_mesh_shader", + "VK_NV_fragment_shader_barycentric", + "VK_NV_shader_image_footprint", + "VK_NV_scissor_exclusive", + "VK_NV_device_diagnostic_checkpoints", + "VK_KHR_timeline_semaphore", + "VK_INTEL_shader_integer_functions2", + "VK_INTEL_performance_query", + "VK_KHR_vulkan_memory_model", + "VK_EXT_pci_bus_info", + "VK_AMD_display_native_hdr", + "VK_KHR_shader_terminate_invocation", + "VK_EXT_fragment_density_map", + "VK_EXT_scalar_block_layout", + "VK_GOOGLE_hlsl_functionality1", + "VK_GOOGLE_decorate_string", + "VK_EXT_subgroup_size_control", + "VK_KHR_fragment_shading_rate", + "VK_AMD_shader_core_properties2", + "VK_AMD_device_coherent_memory", + "VK_KHR_dynamic_rendering_local_read", + "VK_EXT_shader_image_atomic_int64", + "VK_KHR_shader_quad_control", + "VK_KHR_spirv_1_4", + "VK_EXT_memory_budget", + "VK_EXT_memory_priority", + "VK_NV_dedicated_allocation_image_aliasing", + "VK_KHR_separate_depth_stencil_layouts", + "VK_EXT_buffer_device_address", + "VK_EXT_tooling_info", + "VK_EXT_separate_stencil_usage", + "VK_KHR_present_wait", + "VK_NV_cooperative_matrix", + "VK_NV_coverage_reduction_mode", + "VK_EXT_fragment_shader_interlock", + "VK_EXT_ycbcr_image_arrays", + "VK_KHR_uniform_buffer_standard_layout", + "VK_EXT_provoking_vertex", +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + "VK_EXT_full_screen_exclusive", +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + "VK_KHR_buffer_device_address", + "VK_EXT_line_rasterization", + "VK_EXT_shader_atomic_float", + "VK_EXT_host_query_reset", + "VK_EXT_index_type_uint8", + "VK_EXT_extended_dynamic_state", + "VK_KHR_deferred_host_operations", + "VK_KHR_pipeline_executable_properties", + "VK_EXT_host_image_copy", + "VK_KHR_map_memory2", + "VK_EXT_map_memory_placed", + "VK_EXT_shader_atomic_float2", + "VK_EXT_swapchain_maintenance1", + "VK_EXT_shader_demote_to_helper_invocation", + "VK_NV_device_generated_commands", + "VK_NV_inherited_viewport_scissor", + "VK_KHR_shader_integer_dot_product", + "VK_EXT_texel_buffer_alignment", + "VK_QCOM_render_pass_transform", + "VK_EXT_depth_bias_control", + "VK_EXT_device_memory_report", + "VK_EXT_robustness2", + "VK_EXT_custom_border_color", + "VK_GOOGLE_user_type", + "VK_KHR_pipeline_library", + "VK_NV_present_barrier", + "VK_KHR_shader_non_semantic_info", + "VK_KHR_present_id", + "VK_EXT_private_data", + "VK_EXT_pipeline_creation_cache_control", + "VK_KHR_video_encode_queue", + "VK_NV_device_diagnostics_config", + "VK_QCOM_render_pass_store_ops", +#if defined( VK_ENABLE_BETA_EXTENSIONS ) + "VK_NV_cuda_kernel_launch", +#endif /*VK_ENABLE_BETA_EXTENSIONS*/ + "VK_NV_low_latency", +#if defined( VK_USE_PLATFORM_METAL_EXT ) + "VK_EXT_metal_objects", +#endif /*VK_USE_PLATFORM_METAL_EXT*/ + "VK_KHR_synchronization2", + "VK_EXT_descriptor_buffer", + "VK_EXT_graphics_pipeline_library", + "VK_AMD_shader_early_and_late_fragment_tests", + "VK_KHR_fragment_shader_barycentric", + "VK_KHR_shader_subgroup_uniform_control_flow", + "VK_KHR_zero_initialize_workgroup_memory", + "VK_NV_fragment_shading_rate_enums", + "VK_NV_ray_tracing_motion_blur", + "VK_EXT_mesh_shader", + "VK_EXT_ycbcr_2plane_444_formats", + "VK_EXT_fragment_density_map2", + "VK_QCOM_rotated_copy_commands", + "VK_EXT_image_robustness", + "VK_KHR_workgroup_memory_explicit_layout", + "VK_KHR_copy_commands2", + "VK_EXT_image_compression_control", + "VK_EXT_attachment_feedback_loop_layout", + "VK_EXT_4444_formats", + "VK_EXT_device_fault", + "VK_ARM_rasterization_order_attachment_access", + "VK_EXT_rgba10x6_formats", +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + "VK_NV_acquire_winrt_display", +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + "VK_VALVE_mutable_descriptor_type", + "VK_EXT_vertex_input_dynamic_state", + "VK_EXT_physical_device_drm", + "VK_EXT_device_address_binding_report", + "VK_EXT_depth_clip_control", + "VK_EXT_primitive_topology_list_restart", + "VK_KHR_format_feature_flags2", +#if defined( VK_USE_PLATFORM_FUCHSIA ) + "VK_FUCHSIA_external_memory", + "VK_FUCHSIA_external_semaphore", + "VK_FUCHSIA_buffer_collection", +#endif /*VK_USE_PLATFORM_FUCHSIA*/ + "VK_HUAWEI_subpass_shading", + "VK_HUAWEI_invocation_mask", + "VK_NV_external_memory_rdma", + "VK_EXT_pipeline_properties", + "VK_EXT_frame_boundary", + "VK_EXT_multisampled_render_to_single_sampled", + "VK_EXT_extended_dynamic_state2", + "VK_EXT_color_write_enable", + "VK_EXT_primitives_generated_query", + "VK_KHR_ray_tracing_maintenance1", + "VK_EXT_global_priority_query", + "VK_EXT_image_view_min_lod", + "VK_EXT_multi_draw", + "VK_EXT_image_2d_view_of_3d", + "VK_EXT_shader_tile_image", + "VK_EXT_opacity_micromap", +#if defined( VK_ENABLE_BETA_EXTENSIONS ) + "VK_NV_displacement_micromap", +#endif /*VK_ENABLE_BETA_EXTENSIONS*/ + "VK_EXT_load_store_op_none", + "VK_HUAWEI_cluster_culling_shader", + "VK_EXT_border_color_swizzle", + "VK_EXT_pageable_device_local_memory", + "VK_KHR_maintenance4", + "VK_ARM_shader_core_properties", + "VK_KHR_shader_subgroup_rotate", + "VK_ARM_scheduling_controls", + "VK_EXT_image_sliced_view_of_3d", + "VK_VALVE_descriptor_set_host_mapping", + "VK_EXT_depth_clamp_zero_one", + "VK_EXT_non_seamless_cube_map", + "VK_ARM_render_pass_striped", + "VK_QCOM_fragment_density_map_offset", + "VK_NV_copy_memory_indirect", + "VK_NV_memory_decompression", + "VK_NV_device_generated_commands_compute", + "VK_NV_linear_color_attachment", + "VK_KHR_shader_maximal_reconvergence", + "VK_EXT_image_compression_control_swapchain", + "VK_QCOM_image_processing", + "VK_EXT_nested_command_buffer", + "VK_EXT_external_memory_acquire_unmodified", + "VK_EXT_extended_dynamic_state3", + "VK_EXT_subpass_merge_feedback", + "VK_EXT_shader_module_identifier", + "VK_EXT_rasterization_order_attachment_access", + "VK_NV_optical_flow", + "VK_EXT_legacy_dithering", + "VK_EXT_pipeline_protected_access", +#if defined( VK_USE_PLATFORM_ANDROID_KHR ) + "VK_ANDROID_external_format_resolve", +#endif /*VK_USE_PLATFORM_ANDROID_KHR*/ + "VK_KHR_maintenance5", + "VK_KHR_ray_tracing_position_fetch", + "VK_EXT_shader_object", + "VK_QCOM_tile_properties", + "VK_SEC_amigo_profiling", + "VK_QCOM_multiview_per_view_viewports", + "VK_NV_ray_tracing_invocation_reorder", + "VK_NV_extended_sparse_address_space", + "VK_EXT_mutable_descriptor_type", + "VK_ARM_shader_core_builtins", + "VK_EXT_pipeline_library_group_handles", + "VK_EXT_dynamic_rendering_unused_attachments", + "VK_NV_low_latency2", + "VK_KHR_cooperative_matrix", + "VK_QCOM_multiview_per_view_render_areas", + "VK_KHR_video_decode_av1", + "VK_KHR_video_maintenance1", + "VK_NV_per_stage_descriptor_set", + "VK_QCOM_image_processing2", + "VK_QCOM_filter_cubic_weights", + "VK_QCOM_ycbcr_degamma", + "VK_QCOM_filter_cubic_clamp", + "VK_EXT_attachment_feedback_loop_dynamic_state", + "VK_KHR_vertex_attribute_divisor", + "VK_KHR_load_store_op_none", + "VK_KHR_shader_float_controls2", +#if defined( VK_USE_PLATFORM_SCREEN_QNX ) + "VK_QNX_external_memory_screen_buffer", +#endif /*VK_USE_PLATFORM_SCREEN_QNX*/ + "VK_MSFT_layered_driver", + "VK_KHR_index_type_uint8", + "VK_KHR_line_rasterization", + "VK_KHR_calibrated_timestamps", + "VK_KHR_shader_expect_assume", + "VK_KHR_maintenance6", + "VK_NV_descriptor_pool_overallocation", + "VK_NV_raw_access_chains", + "VK_NV_shader_atomic_float16_vector", + "VK_NV_ray_tracing_validation" + }; + return deviceExtensions; + } + + VULKAN_HPP_INLINE std::set const & getInstanceExtensions() + { + static std::set instanceExtensions = { + "VK_KHR_surface", + "VK_KHR_display", +#if defined( VK_USE_PLATFORM_XLIB_KHR ) + "VK_KHR_xlib_surface", +#endif /*VK_USE_PLATFORM_XLIB_KHR*/ +#if defined( VK_USE_PLATFORM_XCB_KHR ) + "VK_KHR_xcb_surface", +#endif /*VK_USE_PLATFORM_XCB_KHR*/ +#if defined( VK_USE_PLATFORM_WAYLAND_KHR ) + "VK_KHR_wayland_surface", +#endif /*VK_USE_PLATFORM_WAYLAND_KHR*/ +#if defined( VK_USE_PLATFORM_ANDROID_KHR ) + "VK_KHR_android_surface", +#endif /*VK_USE_PLATFORM_ANDROID_KHR*/ +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + "VK_KHR_win32_surface", +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + "VK_EXT_debug_report", +#if defined( VK_USE_PLATFORM_GGP ) + "VK_GGP_stream_descriptor_surface", +#endif /*VK_USE_PLATFORM_GGP*/ + "VK_NV_external_memory_capabilities", + "VK_KHR_get_physical_device_properties2", + "VK_EXT_validation_flags", +#if defined( VK_USE_PLATFORM_VI_NN ) + "VK_NN_vi_surface", +#endif /*VK_USE_PLATFORM_VI_NN*/ + "VK_KHR_device_group_creation", + "VK_KHR_external_memory_capabilities", + "VK_KHR_external_semaphore_capabilities", + "VK_EXT_direct_mode_display", +#if defined( VK_USE_PLATFORM_XLIB_XRANDR_EXT ) + "VK_EXT_acquire_xlib_display", +#endif /*VK_USE_PLATFORM_XLIB_XRANDR_EXT*/ + "VK_EXT_display_surface_counter", + "VK_EXT_swapchain_colorspace", + "VK_KHR_external_fence_capabilities", + "VK_KHR_get_surface_capabilities2", + "VK_KHR_get_display_properties2", +#if defined( VK_USE_PLATFORM_IOS_MVK ) + "VK_MVK_ios_surface", +#endif /*VK_USE_PLATFORM_IOS_MVK*/ +#if defined( VK_USE_PLATFORM_MACOS_MVK ) + "VK_MVK_macos_surface", +#endif /*VK_USE_PLATFORM_MACOS_MVK*/ + "VK_EXT_debug_utils", +#if defined( VK_USE_PLATFORM_FUCHSIA ) + "VK_FUCHSIA_imagepipe_surface", +#endif /*VK_USE_PLATFORM_FUCHSIA*/ +#if defined( VK_USE_PLATFORM_METAL_EXT ) + "VK_EXT_metal_surface", +#endif /*VK_USE_PLATFORM_METAL_EXT*/ + "VK_KHR_surface_protected_capabilities", + "VK_EXT_validation_features", + "VK_EXT_headless_surface", + "VK_EXT_surface_maintenance1", + "VK_EXT_acquire_drm_display", +#if defined( VK_USE_PLATFORM_DIRECTFB_EXT ) + "VK_EXT_directfb_surface", +#endif /*VK_USE_PLATFORM_DIRECTFB_EXT*/ +#if defined( VK_USE_PLATFORM_SCREEN_QNX ) + "VK_QNX_screen_surface", +#endif /*VK_USE_PLATFORM_SCREEN_QNX*/ + "VK_KHR_portability_enumeration", + "VK_GOOGLE_surfaceless_query", + "VK_LUNARG_direct_driver_loading", + "VK_EXT_layer_settings" + }; + return instanceExtensions; + } + + VULKAN_HPP_INLINE std::map>> const & getExtensionDepends( std::string const & extension ) + { + static std::map>> noDependencies; + static std::map>>> dependencies = { + { "VK_KHR_swapchain", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, + { "VK_KHR_display", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, + { "VK_KHR_display_swapchain", + { { "VK_VERSION_1_0", + { { + "VK_KHR_swapchain", + "VK_KHR_display", + } } } } }, +#if defined( VK_USE_PLATFORM_XLIB_KHR ) + { "VK_KHR_xlib_surface", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, +#endif /*VK_USE_PLATFORM_XLIB_KHR*/ +#if defined( VK_USE_PLATFORM_XCB_KHR ) + { "VK_KHR_xcb_surface", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, +#endif /*VK_USE_PLATFORM_XCB_KHR*/ +#if defined( VK_USE_PLATFORM_WAYLAND_KHR ) + { "VK_KHR_wayland_surface", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, +#endif /*VK_USE_PLATFORM_WAYLAND_KHR*/ +#if defined( VK_USE_PLATFORM_ANDROID_KHR ) + { "VK_KHR_android_surface", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, +#endif /*VK_USE_PLATFORM_ANDROID_KHR*/ +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + { "VK_KHR_win32_surface", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + { "VK_EXT_debug_marker", + { { "VK_VERSION_1_0", + { { + "VK_EXT_debug_report", + } } } } }, + { "VK_KHR_video_queue", + { { "VK_VERSION_1_1", + { { + "VK_KHR_synchronization2", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_KHR_video_decode_queue", + { { "VK_VERSION_1_0", + { { + "VK_KHR_video_queue", + "VK_KHR_synchronization2", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_EXT_transform_feedback", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_video_encode_h264", + { { "VK_VERSION_1_0", + { { + "VK_KHR_video_encode_queue", + } } } } }, + { "VK_KHR_video_encode_h265", + { { "VK_VERSION_1_0", + { { + "VK_KHR_video_encode_queue", + } } } } }, + { "VK_KHR_video_decode_h264", + { { "VK_VERSION_1_0", + { { + "VK_KHR_video_decode_queue", + } } } } }, + { "VK_AMD_texture_gather_bias_lod", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_dynamic_rendering", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_depth_stencil_resolve", + } } }, + { "VK_VERSION_1_2", { {} } } } }, +#if defined( VK_USE_PLATFORM_GGP ) + { "VK_GGP_stream_descriptor_surface", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, +#endif /*VK_USE_PLATFORM_GGP*/ + { "VK_NV_corner_sampled_image", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_multiview", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_external_memory", + { { "VK_VERSION_1_0", + { { + "VK_NV_external_memory_capabilities", + } } } } }, +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + { "VK_NV_external_memory_win32", + { { "VK_VERSION_1_0", + { { + "VK_NV_external_memory", + } } } } }, + { "VK_NV_win32_keyed_mutex", + { { "VK_VERSION_1_0", + { { + "VK_NV_external_memory_win32", + } } } } }, +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + { "VK_KHR_device_group", + { { "VK_VERSION_1_0", + { { + "VK_KHR_device_group_creation", + } } } } }, +#if defined( VK_USE_PLATFORM_VI_NN ) + { "VK_NN_vi_surface", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, +#endif /*VK_USE_PLATFORM_VI_NN*/ + { "VK_EXT_texture_compression_astc_hdr", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_astc_decode_mode", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_pipeline_robustness", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_external_memory_capabilities", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_external_memory", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_memory_capabilities", + } } }, + { "VK_VERSION_1_1", { {} } } } }, +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + { "VK_KHR_external_memory_win32", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_memory", + } } }, + { "VK_VERSION_1_1", { {} } } } }, +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + { "VK_KHR_external_memory_fd", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_memory", + } } }, + { "VK_VERSION_1_1", { {} } } } }, +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + { "VK_KHR_win32_keyed_mutex", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_memory_win32", + } } } } }, +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + { "VK_KHR_external_semaphore_capabilities", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_external_semaphore", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_semaphore_capabilities", + } } } } }, +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + { "VK_KHR_external_semaphore_win32", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_semaphore", + } } } } }, +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + { "VK_KHR_external_semaphore_fd", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_semaphore", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_push_descriptor", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_conditional_rendering", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_shader_float16_int8", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_16bit_storage", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + "VK_KHR_storage_buffer_storage_class", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_incremental_present", + { { "VK_VERSION_1_0", + { { + "VK_KHR_swapchain", + } } } } }, + { "VK_EXT_direct_mode_display", + { { "VK_VERSION_1_0", + { { + "VK_KHR_display", + } } } } }, +#if defined( VK_USE_PLATFORM_XLIB_XRANDR_EXT ) + { "VK_EXT_acquire_xlib_display", + { { "VK_VERSION_1_0", + { { + "VK_EXT_direct_mode_display", + } } } } }, +#endif /*VK_USE_PLATFORM_XLIB_XRANDR_EXT*/ + { "VK_EXT_display_surface_counter", + { { "VK_VERSION_1_0", + { { + "VK_KHR_display", + } } } } }, + { "VK_EXT_display_control", + { { "VK_VERSION_1_0", + { { + "VK_EXT_display_surface_counter", + "VK_KHR_swapchain", + } } } } }, + { "VK_GOOGLE_display_timing", + { { "VK_VERSION_1_0", + { { + "VK_KHR_swapchain", + } } } } }, + { "VK_NVX_multiview_per_view_attributes", + { { "VK_VERSION_1_0", + { { + "VK_KHR_multiview", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_discard_rectangles", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_conservative_rasterization", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_depth_clip_enable", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_swapchain_colorspace", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, + { "VK_EXT_hdr_metadata", + { { "VK_VERSION_1_0", + { { + "VK_KHR_swapchain", + } } } } }, + { "VK_KHR_imageless_framebuffer", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + "VK_KHR_maintenance2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_image_format_list", + } } }, + { "VK_VERSION_1_2", { {} } } } }, + { "VK_KHR_create_renderpass2", + { { "VK_VERSION_1_0", + { { + "VK_KHR_multiview", + "VK_KHR_maintenance2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_IMG_relaxed_line_rasterization", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_shared_presentable_image", + { { "VK_VERSION_1_0", + { { + "VK_KHR_swapchain", + "VK_KHR_get_surface_capabilities2", + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_swapchain", + "VK_KHR_get_surface_capabilities2", + } } } } }, + { "VK_KHR_external_fence_capabilities", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_external_fence", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_fence_capabilities", + } } } } }, +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + { "VK_KHR_external_fence_win32", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_fence", + } } } } }, +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + { "VK_KHR_external_fence_fd", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_fence", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_performance_query", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_get_surface_capabilities2", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, + { "VK_KHR_variable_pointers", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + "VK_KHR_storage_buffer_storage_class", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_get_display_properties2", + { { "VK_VERSION_1_0", + { { + "VK_KHR_display", + } } } } }, +#if defined( VK_USE_PLATFORM_IOS_MVK ) + { "VK_MVK_ios_surface", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, +#endif /*VK_USE_PLATFORM_IOS_MVK*/ +#if defined( VK_USE_PLATFORM_MACOS_MVK ) + { "VK_MVK_macos_surface", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, +#endif /*VK_USE_PLATFORM_MACOS_MVK*/ + { "VK_EXT_external_memory_dma_buf", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_memory_fd", + } } } } }, + { "VK_EXT_queue_family_foreign", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_memory", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_dedicated_allocation", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_memory_requirements2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, +#if defined( VK_USE_PLATFORM_ANDROID_KHR ) + { "VK_ANDROID_external_memory_android_hardware_buffer", + { { "VK_VERSION_1_0", + { { + "VK_KHR_sampler_ycbcr_conversion", + "VK_KHR_external_memory", + "VK_KHR_dedicated_allocation", + } } }, + { "VK_VERSION_1_1", + { { + "VK_EXT_queue_family_foreign", + } } } } }, +#endif /*VK_USE_PLATFORM_ANDROID_KHR*/ + { "VK_EXT_sampler_filter_minmax", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, +#if defined( VK_ENABLE_BETA_EXTENSIONS ) + { "VK_AMDX_shader_enqueue", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_synchronization2", + } } }, + { "VK_VERSION_1_3", + { { + "VK_KHR_pipeline_library", + "VK_KHR_spirv_1_4", + } } } } }, +#endif /*VK_ENABLE_BETA_EXTENSIONS*/ + { "VK_EXT_inline_uniform_block", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + "VK_KHR_maintenance1", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_sample_locations", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_blend_operation_advanced", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_acceleration_structure", + { { "VK_VERSION_1_1", + { { + "VK_EXT_descriptor_indexing", + "VK_KHR_buffer_device_address", + } } }, + { "VK_VERSION_1_2", + { { + "VK_KHR_deferred_host_operations", + } } } } }, + { "VK_KHR_ray_tracing_pipeline", + { { "VK_VERSION_1_0", + { { + "VK_KHR_spirv_1_4", + "VK_KHR_acceleration_structure", + } } } } }, + { "VK_KHR_ray_query", + { { "VK_VERSION_1_0", + { { + "VK_KHR_spirv_1_4", + "VK_KHR_acceleration_structure", + } } } } }, + { "VK_NV_shader_sm_builtins", { { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_sampler_ycbcr_conversion", + { { "VK_VERSION_1_0", + { { + "VK_KHR_maintenance1", + "VK_KHR_bind_memory2", + "VK_KHR_get_memory_requirements2", + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_image_drm_format_modifier", + { { "VK_VERSION_1_0", + { { + "VK_KHR_bind_memory2", + "VK_KHR_get_physical_device_properties2", + "VK_KHR_sampler_ycbcr_conversion", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_image_format_list", + } } }, + { "VK_VERSION_1_2", { {} } } } }, + { "VK_EXT_descriptor_indexing", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + "VK_KHR_maintenance3", + } } }, + { "VK_VERSION_1_1", { {} } } } }, +#if defined( VK_ENABLE_BETA_EXTENSIONS ) + { "VK_KHR_portability_subset", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, +#endif /*VK_ENABLE_BETA_EXTENSIONS*/ + { "VK_NV_shading_rate_image", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_ray_tracing", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + "VK_KHR_get_memory_requirements2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_representative_fragment_test", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_maintenance3", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_shader_subgroup_extended_types", { { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_8bit_storage", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + "VK_KHR_storage_buffer_storage_class", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_external_memory_host", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_memory", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_shader_atomic_int64", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_shader_clock", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_calibrated_timestamps", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_AMD_shader_core_properties", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_video_decode_h265", + { { "VK_VERSION_1_0", + { { + "VK_KHR_video_decode_queue", + } } } } }, + { "VK_KHR_global_priority", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_vertex_attribute_divisor", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, +#if defined( VK_USE_PLATFORM_GGP ) + { "VK_GGP_frame_token", + { { "VK_VERSION_1_0", + { { + "VK_KHR_swapchain", + "VK_GGP_stream_descriptor_surface", + } } } } }, +#endif /*VK_USE_PLATFORM_GGP*/ + { "VK_KHR_driver_properties", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_shader_float_controls", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_shader_subgroup_partitioned", { { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_depth_stencil_resolve", + { { "VK_VERSION_1_0", + { { + "VK_KHR_create_renderpass2", + } } }, + { "VK_VERSION_1_2", { {} } } } }, + { "VK_KHR_swapchain_mutable_format", + { { "VK_VERSION_1_0", + { { + "VK_KHR_swapchain", + "VK_KHR_maintenance2", + "VK_KHR_image_format_list", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_swapchain", + "VK_KHR_image_format_list", + } } }, + { "VK_VERSION_1_2", + { { + "VK_KHR_swapchain", + } } } } }, + { "VK_NV_compute_shader_derivatives", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_mesh_shader", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_fragment_shader_barycentric", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_shader_image_footprint", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_scissor_exclusive", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_device_diagnostic_checkpoints", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_timeline_semaphore", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_INTEL_shader_integer_functions2", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_vulkan_memory_model", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_pci_bus_info", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_AMD_display_native_hdr", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_get_surface_capabilities2", + "VK_KHR_swapchain", + } } } } }, +#if defined( VK_USE_PLATFORM_FUCHSIA ) + { "VK_FUCHSIA_imagepipe_surface", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, +#endif /*VK_USE_PLATFORM_FUCHSIA*/ + { "VK_KHR_shader_terminate_invocation", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, +#if defined( VK_USE_PLATFORM_METAL_EXT ) + { "VK_EXT_metal_surface", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, +#endif /*VK_USE_PLATFORM_METAL_EXT*/ + { "VK_EXT_fragment_density_map", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_scalar_block_layout", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_subgroup_size_control", { { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_fragment_shading_rate", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_create_renderpass2", + } } }, + { "VK_VERSION_1_2", { {} } } } }, + { "VK_AMD_shader_core_properties2", + { { "VK_VERSION_1_0", + { { + "VK_AMD_shader_core_properties", + } } } } }, + { "VK_AMD_device_coherent_memory", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_dynamic_rendering_local_read", + { { "VK_VERSION_1_0", + { { + "VK_KHR_dynamic_rendering", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_EXT_shader_image_atomic_int64", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_shader_quad_control", + { { "VK_VERSION_1_1", + { { + "VK_KHR_vulkan_memory_model", + "VK_KHR_shader_maximal_reconvergence", + } } } } }, + { "VK_KHR_spirv_1_4", + { { "VK_VERSION_1_1", + { { + "VK_KHR_shader_float_controls", + } } } } }, + { "VK_EXT_memory_budget", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_memory_priority", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_surface_protected_capabilities", + { { "VK_VERSION_1_1", + { { + "VK_KHR_get_surface_capabilities2", + } } } } }, + { "VK_NV_dedicated_allocation_image_aliasing", + { { "VK_VERSION_1_0", + { { + "VK_KHR_dedicated_allocation", + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_separate_depth_stencil_layouts", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_create_renderpass2", + } } }, + { "VK_VERSION_1_2", { {} } } } }, + { "VK_EXT_buffer_device_address", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_present_wait", + { { "VK_VERSION_1_0", + { { + "VK_KHR_swapchain", + "VK_KHR_present_id", + } } } } }, + { "VK_NV_cooperative_matrix", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_coverage_reduction_mode", + { { "VK_VERSION_1_0", + { { + "VK_NV_framebuffer_mixed_samples", + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_fragment_shader_interlock", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_ycbcr_image_arrays", + { { "VK_VERSION_1_0", + { { + "VK_KHR_sampler_ycbcr_conversion", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_uniform_buffer_standard_layout", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_provoking_vertex", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + { "VK_EXT_full_screen_exclusive", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_surface", + "VK_KHR_get_surface_capabilities2", + "VK_KHR_swapchain", + } } } } }, +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + { "VK_EXT_headless_surface", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, + { "VK_KHR_buffer_device_address", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + "VK_KHR_device_group", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_line_rasterization", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_shader_atomic_float", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_host_query_reset", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_index_type_uint8", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_extended_dynamic_state", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_pipeline_executable_properties", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_host_image_copy", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_copy_commands2", + "VK_KHR_format_feature_flags2", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_EXT_map_memory_placed", + { { "VK_VERSION_1_0", + { { + "VK_KHR_map_memory2", + } } } } }, + { "VK_EXT_shader_atomic_float2", + { { "VK_VERSION_1_0", + { { + "VK_EXT_shader_atomic_float", + } } } } }, + { "VK_EXT_surface_maintenance1", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + "VK_KHR_get_surface_capabilities2", + } } } } }, + { "VK_EXT_swapchain_maintenance1", + { { "VK_VERSION_1_0", + { { + "VK_KHR_swapchain", + "VK_EXT_surface_maintenance1", + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_shader_demote_to_helper_invocation", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_device_generated_commands", + { { "VK_VERSION_1_1", + { { + "VK_KHR_buffer_device_address", + } } }, + { "VK_VERSION_1_2", { {} } } } }, + { "VK_NV_inherited_viewport_scissor", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_shader_integer_dot_product", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_texel_buffer_alignment", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_depth_bias_control", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_device_memory_report", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_acquire_drm_display", + { { "VK_VERSION_1_0", + { { + "VK_EXT_direct_mode_display", + } } } } }, + { "VK_EXT_robustness2", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_custom_border_color", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_present_barrier", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_surface", + "VK_KHR_get_surface_capabilities2", + "VK_KHR_swapchain", + } } } } }, + { "VK_KHR_present_id", + { { "VK_VERSION_1_0", + { { + "VK_KHR_swapchain", + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_private_data", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_pipeline_creation_cache_control", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_video_encode_queue", + { { "VK_VERSION_1_0", + { { + "VK_KHR_video_queue", + "VK_KHR_synchronization2", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_NV_device_diagnostics_config", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_synchronization2", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_descriptor_buffer", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_buffer_device_address", + "VK_EXT_descriptor_indexing", + } } }, + { "VK_VERSION_1_2", + { { + "VK_KHR_synchronization2", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_EXT_graphics_pipeline_library", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_pipeline_library", + } } } } }, + { "VK_AMD_shader_early_and_late_fragment_tests", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_fragment_shader_barycentric", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_shader_subgroup_uniform_control_flow", { { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_zero_initialize_workgroup_memory", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_fragment_shading_rate_enums", + { { "VK_VERSION_1_0", + { { + "VK_KHR_fragment_shading_rate", + } } } } }, + { "VK_NV_ray_tracing_motion_blur", + { { "VK_VERSION_1_0", + { { + "VK_KHR_ray_tracing_pipeline", + } } } } }, + { "VK_EXT_mesh_shader", + { { "VK_VERSION_1_0", + { { + "VK_KHR_spirv_1_4", + } } } } }, + { "VK_EXT_ycbcr_2plane_444_formats", + { { "VK_VERSION_1_0", + { { + "VK_KHR_sampler_ycbcr_conversion", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_fragment_density_map2", + { { "VK_VERSION_1_0", + { { + "VK_EXT_fragment_density_map", + } } } } }, + { "VK_QCOM_rotated_copy_commands", + { { "VK_VERSION_1_0", + { { + "VK_KHR_copy_commands2", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_EXT_image_robustness", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_workgroup_memory_explicit_layout", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_copy_commands2", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_image_compression_control", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_attachment_feedback_loop_layout", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_4444_formats", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_device_fault", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_ARM_rasterization_order_attachment_access", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_rgba10x6_formats", + { { "VK_VERSION_1_0", + { { + "VK_KHR_sampler_ycbcr_conversion", + } } }, + { "VK_VERSION_1_1", { {} } } } }, +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + { "VK_NV_acquire_winrt_display", + { { "VK_VERSION_1_0", + { { + "VK_EXT_direct_mode_display", + } } } } }, +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ +#if defined( VK_USE_PLATFORM_DIRECTFB_EXT ) + { "VK_EXT_directfb_surface", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, +#endif /*VK_USE_PLATFORM_DIRECTFB_EXT*/ + { "VK_VALVE_mutable_descriptor_type", + { { "VK_VERSION_1_0", + { { + "VK_KHR_maintenance3", + } } } } }, + { "VK_EXT_vertex_input_dynamic_state", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_physical_device_drm", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_device_address_binding_report", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_EXT_debug_utils", + } } } } }, + { "VK_EXT_depth_clip_control", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_primitive_topology_list_restart", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_format_feature_flags2", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, +#if defined( VK_USE_PLATFORM_FUCHSIA ) + { "VK_FUCHSIA_external_memory", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_memory_capabilities", + "VK_KHR_external_memory", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_FUCHSIA_external_semaphore", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_semaphore_capabilities", + "VK_KHR_external_semaphore", + } } } } }, + { "VK_FUCHSIA_buffer_collection", + { { "VK_VERSION_1_0", + { { + "VK_FUCHSIA_external_memory", + "VK_KHR_sampler_ycbcr_conversion", + } } }, + { "VK_VERSION_1_1", { {} } } } }, +#endif /*VK_USE_PLATFORM_FUCHSIA*/ + { "VK_HUAWEI_subpass_shading", + { { "VK_VERSION_1_0", + { { + "VK_KHR_create_renderpass2", + } } }, + { "VK_VERSION_1_2", + { { + "VK_KHR_synchronization2", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_HUAWEI_invocation_mask", + { { "VK_VERSION_1_0", + { { + "VK_KHR_ray_tracing_pipeline", + "VK_KHR_synchronization2", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_NV_external_memory_rdma", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_memory", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_pipeline_properties", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_multisampled_render_to_single_sampled", + { { "VK_VERSION_1_0", + { { + "VK_KHR_create_renderpass2", + "VK_KHR_depth_stencil_resolve", + } } }, + { "VK_VERSION_1_2", { {} } } } }, + { "VK_EXT_extended_dynamic_state2", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, +#if defined( VK_USE_PLATFORM_SCREEN_QNX ) + { "VK_QNX_screen_surface", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, +#endif /*VK_USE_PLATFORM_SCREEN_QNX*/ + { "VK_EXT_color_write_enable", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_primitives_generated_query", + { { "VK_VERSION_1_0", + { { + "VK_EXT_transform_feedback", + } } } } }, + { "VK_KHR_ray_tracing_maintenance1", + { { "VK_VERSION_1_0", + { { + "VK_KHR_acceleration_structure", + } } } } }, + { "VK_EXT_global_priority_query", + { { "VK_VERSION_1_0", + { { + "VK_EXT_global_priority", + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_image_view_min_lod", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_multi_draw", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_image_2d_view_of_3d", + { { "VK_VERSION_1_0", + { { + "VK_KHR_maintenance1", + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_shader_tile_image", { { "VK_VERSION_1_3", { {} } } } }, + { "VK_EXT_opacity_micromap", + { { "VK_VERSION_1_0", + { { + "VK_KHR_acceleration_structure", + "VK_KHR_synchronization2", + } } }, + { "VK_VERSION_1_3", { {} } } } }, +#if defined( VK_ENABLE_BETA_EXTENSIONS ) + { "VK_NV_displacement_micromap", + { { "VK_VERSION_1_0", + { { + "VK_EXT_opacity_micromap", + } } } } }, +#endif /*VK_ENABLE_BETA_EXTENSIONS*/ + { "VK_HUAWEI_cluster_culling_shader", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_border_color_swizzle", + { { "VK_VERSION_1_0", + { { + "VK_EXT_custom_border_color", + } } } } }, + { "VK_EXT_pageable_device_local_memory", + { { "VK_VERSION_1_0", + { { + "VK_EXT_memory_priority", + } } } } }, + { "VK_KHR_maintenance4", { { "VK_VERSION_1_1", { {} } } } }, + { "VK_ARM_shader_core_properties", { { "VK_VERSION_1_1", { {} } } } }, + { "VK_ARM_scheduling_controls", + { { "VK_VERSION_1_0", + { { + "VK_ARM_shader_core_builtins", + } } } } }, + { "VK_EXT_image_sliced_view_of_3d", + { { "VK_VERSION_1_0", + { { + "VK_KHR_maintenance1", + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_VALVE_descriptor_set_host_mapping", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_depth_clamp_zero_one", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_non_seamless_cube_map", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_ARM_render_pass_striped", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_synchronization2", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_QCOM_fragment_density_map_offset", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_EXT_fragment_density_map", + } } } } }, + { "VK_NV_copy_memory_indirect", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_buffer_device_address", + } } }, + { "VK_VERSION_1_2", { {} } } } }, + { "VK_NV_memory_decompression", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_buffer_device_address", + } } }, + { "VK_VERSION_1_2", { {} } } } }, + { "VK_NV_device_generated_commands_compute", + { { "VK_VERSION_1_0", + { { + "VK_NV_device_generated_commands", + } } } } }, + { "VK_NV_linear_color_attachment", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_GOOGLE_surfaceless_query", + { { "VK_VERSION_1_0", + { { + "VK_KHR_surface", + } } } } }, + { "VK_KHR_shader_maximal_reconvergence", { { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_image_compression_control_swapchain", + { { "VK_VERSION_1_0", + { { + "VK_EXT_image_compression_control", + } } } } }, + { "VK_QCOM_image_processing", + { { "VK_VERSION_1_0", + { { + "VK_KHR_format_feature_flags2", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_EXT_nested_command_buffer", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_external_memory_acquire_unmodified", + { { "VK_VERSION_1_0", + { { + "VK_KHR_external_memory", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_extended_dynamic_state3", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_subpass_merge_feedback", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_shader_module_identifier", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_EXT_pipeline_creation_cache_control", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_EXT_rasterization_order_attachment_access", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_optical_flow", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_format_feature_flags2", + "VK_KHR_synchronization2", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_EXT_legacy_dithering", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_pipeline_protected_access", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, +#if defined( VK_USE_PLATFORM_ANDROID_KHR ) + { "VK_ANDROID_external_format_resolve", + { { "VK_VERSION_1_0", + { { + "VK_ANDROID_external_memory_android_hardware_buffer", + } } } } }, +#endif /*VK_USE_PLATFORM_ANDROID_KHR*/ + { "VK_KHR_maintenance5", + { { "VK_VERSION_1_1", + { { + "VK_KHR_dynamic_rendering", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_KHR_ray_tracing_position_fetch", + { { "VK_VERSION_1_0", + { { + "VK_KHR_acceleration_structure", + } } } } }, + { "VK_EXT_shader_object", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_dynamic_rendering", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_QCOM_tile_properties", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_SEC_amigo_profiling", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_QCOM_multiview_per_view_viewports", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_ray_tracing_invocation_reorder", + { { "VK_VERSION_1_0", + { { + "VK_KHR_ray_tracing_pipeline", + } } } } }, + { "VK_EXT_mutable_descriptor_type", + { { "VK_VERSION_1_0", + { { + "VK_KHR_maintenance3", + } } } } }, + { "VK_ARM_shader_core_builtins", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_EXT_pipeline_library_group_handles", + { { "VK_VERSION_1_0", + { { + "VK_KHR_ray_tracing_pipeline", + "VK_KHR_pipeline_library", + } } } } }, + { "VK_EXT_dynamic_rendering_unused_attachments", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_KHR_dynamic_rendering", + } } }, + { "VK_VERSION_1_3", { {} } } } }, + { "VK_NV_low_latency2", + { { "VK_VERSION_1_0", + { { + "VK_KHR_timeline_semaphore", + } } }, + { "VK_VERSION_1_2", { {} } } } }, + { "VK_KHR_cooperative_matrix", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_video_decode_av1", + { { "VK_VERSION_1_0", + { { + "VK_KHR_video_decode_queue", + } } } } }, + { "VK_KHR_video_maintenance1", + { { "VK_VERSION_1_0", + { { + "VK_KHR_video_queue", + } } } } }, + { "VK_NV_per_stage_descriptor_set", + { { "VK_VERSION_1_0", + { { + "VK_KHR_maintenance6", + } } } } }, + { "VK_QCOM_image_processing2", + { { "VK_VERSION_1_0", + { { + "VK_QCOM_image_processing", + } } } } }, + { "VK_QCOM_filter_cubic_weights", + { { "VK_VERSION_1_0", + { { + "VK_EXT_filter_cubic", + } } } } }, + { "VK_QCOM_filter_cubic_clamp", + { { "VK_VERSION_1_0", + { { + "VK_EXT_filter_cubic", + "VK_EXT_sampler_filter_minmax", + } } }, + { "VK_VERSION_1_2", + { { + "VK_EXT_filter_cubic", + } } } } }, + { "VK_EXT_attachment_feedback_loop_dynamic_state", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", + { { + "VK_EXT_attachment_feedback_loop_layout", + } } } } }, + { "VK_KHR_vertex_attribute_divisor", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_shader_float_controls2", + { { "VK_VERSION_1_1", + { { + "VK_KHR_shader_float_controls", + } } } } }, +#if defined( VK_USE_PLATFORM_SCREEN_QNX ) + { "VK_QNX_external_memory_screen_buffer", + { { "VK_VERSION_1_0", + { { + "VK_KHR_sampler_ycbcr_conversion", + "VK_KHR_external_memory", + "VK_KHR_dedicated_allocation", + } } }, + { "VK_VERSION_1_1", + { { + "VK_EXT_queue_family_foreign", + } } } } }, +#endif /*VK_USE_PLATFORM_SCREEN_QNX*/ + { "VK_MSFT_layered_driver", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_index_type_uint8", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_line_rasterization", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_calibrated_timestamps", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_shader_expect_assume", + { { "VK_VERSION_1_0", + { { + "VK_KHR_get_physical_device_properties2", + } } }, + { "VK_VERSION_1_1", { {} } } } }, + { "VK_KHR_maintenance6", { { "VK_VERSION_1_1", { {} } } } }, + { "VK_NV_descriptor_pool_overallocation", { { "VK_VERSION_1_1", { {} } } } } + }; + auto depIt = dependencies.find( extension ); + return ( depIt != dependencies.end() ) ? depIt->second : noDependencies; + } + + VULKAN_HPP_INLINE std::pair> const &> getExtensionDepends( std::string const & version, + std::string const & extension ) + { +#if !defined( NDEBUG ) + static std::set versions = { "VK_VERSION_1_0", "VK_VERSION_1_1", "VK_VERSION_1_2", "VK_VERSION_1_3" }; + assert( versions.find( version ) != versions.end() ); +#endif + static std::vector> noDependencies; + + std::map>> const & dependencies = getExtensionDepends( extension ); + if ( dependencies.empty() ) + { + return { true, noDependencies }; + } + auto depIt = dependencies.lower_bound( version ); + if ( ( depIt == dependencies.end() ) || ( depIt->first != version ) ) + { + depIt = std::prev( depIt ); + } + if ( depIt == dependencies.end() ) + { + return { false, noDependencies }; + } + else + { + return { true, depIt->second }; + } + } + + VULKAN_HPP_INLINE std::map const & getObsoletedExtensions() + { + static std::map obsoletedExtensions = { { "VK_AMD_negative_viewport_height", "VK_KHR_maintenance1" } }; + return obsoletedExtensions; + } + + VULKAN_HPP_INLINE std::map const & getPromotedExtensions() + { + static std::map promotedExtensions = { + { "VK_KHR_sampler_mirror_clamp_to_edge", "VK_VERSION_1_2" }, + { "VK_EXT_debug_marker", "VK_EXT_debug_utils" }, + { "VK_AMD_draw_indirect_count", "VK_KHR_draw_indirect_count" }, + { "VK_KHR_dynamic_rendering", "VK_VERSION_1_3" }, + { "VK_KHR_multiview", "VK_VERSION_1_1" }, +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + { "VK_NV_win32_keyed_mutex", "VK_KHR_win32_keyed_mutex" }, +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + { "VK_KHR_get_physical_device_properties2", "VK_VERSION_1_1" }, + { "VK_KHR_device_group", "VK_VERSION_1_1" }, + { "VK_KHR_shader_draw_parameters", "VK_VERSION_1_1" }, + { "VK_EXT_texture_compression_astc_hdr", "VK_VERSION_1_3" }, + { "VK_KHR_maintenance1", "VK_VERSION_1_1" }, + { "VK_KHR_device_group_creation", "VK_VERSION_1_1" }, + { "VK_KHR_external_memory_capabilities", "VK_VERSION_1_1" }, + { "VK_KHR_external_memory", "VK_VERSION_1_1" }, + { "VK_KHR_external_semaphore_capabilities", "VK_VERSION_1_1" }, + { "VK_KHR_external_semaphore", "VK_VERSION_1_1" }, + { "VK_KHR_shader_float16_int8", "VK_VERSION_1_2" }, + { "VK_KHR_16bit_storage", "VK_VERSION_1_1" }, + { "VK_KHR_descriptor_update_template", "VK_VERSION_1_1" }, + { "VK_KHR_imageless_framebuffer", "VK_VERSION_1_2" }, + { "VK_KHR_create_renderpass2", "VK_VERSION_1_2" }, + { "VK_KHR_external_fence_capabilities", "VK_VERSION_1_1" }, + { "VK_KHR_external_fence", "VK_VERSION_1_1" }, + { "VK_KHR_maintenance2", "VK_VERSION_1_1" }, + { "VK_KHR_variable_pointers", "VK_VERSION_1_1" }, + { "VK_KHR_dedicated_allocation", "VK_VERSION_1_1" }, + { "VK_EXT_sampler_filter_minmax", "VK_VERSION_1_2" }, + { "VK_KHR_storage_buffer_storage_class", "VK_VERSION_1_1" }, + { "VK_EXT_inline_uniform_block", "VK_VERSION_1_3" }, + { "VK_KHR_relaxed_block_layout", "VK_VERSION_1_1" }, + { "VK_KHR_get_memory_requirements2", "VK_VERSION_1_1" }, + { "VK_KHR_image_format_list", "VK_VERSION_1_2" }, + { "VK_KHR_sampler_ycbcr_conversion", "VK_VERSION_1_1" }, + { "VK_KHR_bind_memory2", "VK_VERSION_1_1" }, + { "VK_EXT_descriptor_indexing", "VK_VERSION_1_2" }, + { "VK_EXT_shader_viewport_index_layer", "VK_VERSION_1_2" }, + { "VK_KHR_maintenance3", "VK_VERSION_1_1" }, + { "VK_KHR_draw_indirect_count", "VK_VERSION_1_2" }, + { "VK_EXT_global_priority", "VK_KHR_global_priority" }, + { "VK_KHR_shader_subgroup_extended_types", "VK_VERSION_1_2" }, + { "VK_KHR_8bit_storage", "VK_VERSION_1_2" }, + { "VK_KHR_shader_atomic_int64", "VK_VERSION_1_2" }, + { "VK_EXT_calibrated_timestamps", "VK_KHR_calibrated_timestamps" }, + { "VK_EXT_vertex_attribute_divisor", "VK_KHR_vertex_attribute_divisor" }, + { "VK_EXT_pipeline_creation_feedback", "VK_VERSION_1_3" }, + { "VK_KHR_driver_properties", "VK_VERSION_1_2" }, + { "VK_KHR_shader_float_controls", "VK_VERSION_1_2" }, + { "VK_KHR_depth_stencil_resolve", "VK_VERSION_1_2" }, + { "VK_NV_fragment_shader_barycentric", "VK_KHR_fragment_shader_barycentric" }, + { "VK_KHR_timeline_semaphore", "VK_VERSION_1_2" }, + { "VK_KHR_vulkan_memory_model", "VK_VERSION_1_2" }, + { "VK_KHR_shader_terminate_invocation", "VK_VERSION_1_3" }, + { "VK_EXT_scalar_block_layout", "VK_VERSION_1_2" }, + { "VK_EXT_subgroup_size_control", "VK_VERSION_1_3" }, + { "VK_KHR_spirv_1_4", "VK_VERSION_1_2" }, + { "VK_KHR_separate_depth_stencil_layouts", "VK_VERSION_1_2" }, + { "VK_EXT_tooling_info", "VK_VERSION_1_3" }, + { "VK_EXT_separate_stencil_usage", "VK_VERSION_1_2" }, + { "VK_KHR_uniform_buffer_standard_layout", "VK_VERSION_1_2" }, + { "VK_KHR_buffer_device_address", "VK_VERSION_1_2" }, + { "VK_EXT_line_rasterization", "VK_KHR_line_rasterization" }, + { "VK_EXT_host_query_reset", "VK_VERSION_1_2" }, + { "VK_EXT_index_type_uint8", "VK_KHR_index_type_uint8" }, + { "VK_EXT_extended_dynamic_state", "VK_VERSION_1_3" }, + { "VK_EXT_shader_demote_to_helper_invocation", "VK_VERSION_1_3" }, + { "VK_KHR_shader_integer_dot_product", "VK_VERSION_1_3" }, + { "VK_EXT_texel_buffer_alignment", "VK_VERSION_1_3" }, + { "VK_KHR_shader_non_semantic_info", "VK_VERSION_1_3" }, + { "VK_EXT_private_data", "VK_VERSION_1_3" }, + { "VK_EXT_pipeline_creation_cache_control", "VK_VERSION_1_3" }, + { "VK_KHR_synchronization2", "VK_VERSION_1_3" }, + { "VK_KHR_zero_initialize_workgroup_memory", "VK_VERSION_1_3" }, + { "VK_EXT_ycbcr_2plane_444_formats", "VK_VERSION_1_3" }, + { "VK_EXT_image_robustness", "VK_VERSION_1_3" }, + { "VK_KHR_copy_commands2", "VK_VERSION_1_3" }, + { "VK_EXT_4444_formats", "VK_VERSION_1_3" }, + { "VK_ARM_rasterization_order_attachment_access", "VK_EXT_rasterization_order_attachment_access" }, + { "VK_VALVE_mutable_descriptor_type", "VK_EXT_mutable_descriptor_type" }, + { "VK_KHR_format_feature_flags2", "VK_VERSION_1_3" }, + { "VK_EXT_extended_dynamic_state2", "VK_VERSION_1_3" }, + { "VK_EXT_global_priority_query", "VK_KHR_global_priority" }, + { "VK_EXT_load_store_op_none", "VK_KHR_load_store_op_none" }, + { "VK_KHR_maintenance4", "VK_VERSION_1_3" } + }; + return promotedExtensions; + } + + VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR_20 std::string getExtensionDeprecatedBy( std::string const & extension ) + { + if ( extension == "VK_EXT_debug_report" ) + { + return "VK_EXT_debug_utils"; + } + if ( extension == "VK_NV_glsl_shader" ) + { + return ""; + } + if ( extension == "VK_NV_dedicated_allocation" ) + { + return "VK_KHR_dedicated_allocation"; + } + if ( extension == "VK_AMD_gpu_shader_half_float" ) + { + return "VK_KHR_shader_float16_int8"; + } + if ( extension == "VK_IMG_format_pvrtc" ) + { + return ""; + } + if ( extension == "VK_NV_external_memory_capabilities" ) + { + return "VK_KHR_external_memory_capabilities"; + } + if ( extension == "VK_NV_external_memory" ) + { + return "VK_KHR_external_memory"; + } +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + if ( extension == "VK_NV_external_memory_win32" ) + { + return "VK_KHR_external_memory_win32"; + } +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + if ( extension == "VK_EXT_validation_flags" ) + { + return "VK_EXT_layer_settings"; + } + if ( extension == "VK_EXT_shader_subgroup_ballot" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_EXT_shader_subgroup_vote" ) + { + return "VK_VERSION_1_1"; + } +#if defined( VK_USE_PLATFORM_IOS_MVK ) + if ( extension == "VK_MVK_ios_surface" ) + { + return "VK_EXT_metal_surface"; + } +#endif /*VK_USE_PLATFORM_IOS_MVK*/ +#if defined( VK_USE_PLATFORM_MACOS_MVK ) + if ( extension == "VK_MVK_macos_surface" ) + { + return "VK_EXT_metal_surface"; + } +#endif /*VK_USE_PLATFORM_MACOS_MVK*/ + if ( extension == "VK_AMD_gpu_shader_int16" ) + { + return "VK_KHR_shader_float16_int8"; + } + if ( extension == "VK_EXT_buffer_device_address" ) + { + return "VK_KHR_buffer_device_address"; + } + if ( extension == "VK_EXT_validation_features" ) + { + return "VK_EXT_layer_settings"; + } + return ""; + } + + VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR_20 std::string getExtensionObsoletedBy( std::string const & extension ) + { + if ( extension == "VK_AMD_negative_viewport_height" ) + { + return "VK_KHR_maintenance1"; + } + return ""; + } + + VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR_20 std::string getExtensionPromotedTo( std::string const & extension ) + { + if ( extension == "VK_KHR_sampler_mirror_clamp_to_edge" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_EXT_debug_marker" ) + { + return "VK_EXT_debug_utils"; + } + if ( extension == "VK_AMD_draw_indirect_count" ) + { + return "VK_KHR_draw_indirect_count"; + } + if ( extension == "VK_KHR_dynamic_rendering" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_KHR_multiview" ) + { + return "VK_VERSION_1_1"; + } +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + if ( extension == "VK_NV_win32_keyed_mutex" ) + { + return "VK_KHR_win32_keyed_mutex"; + } +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + if ( extension == "VK_KHR_get_physical_device_properties2" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_device_group" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_shader_draw_parameters" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_EXT_texture_compression_astc_hdr" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_KHR_maintenance1" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_device_group_creation" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_external_memory_capabilities" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_external_memory" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_external_semaphore_capabilities" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_external_semaphore" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_shader_float16_int8" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_KHR_16bit_storage" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_descriptor_update_template" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_imageless_framebuffer" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_KHR_create_renderpass2" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_KHR_external_fence_capabilities" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_external_fence" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_maintenance2" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_variable_pointers" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_dedicated_allocation" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_EXT_sampler_filter_minmax" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_KHR_storage_buffer_storage_class" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_EXT_inline_uniform_block" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_KHR_relaxed_block_layout" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_get_memory_requirements2" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_image_format_list" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_KHR_sampler_ycbcr_conversion" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_bind_memory2" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_EXT_descriptor_indexing" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_EXT_shader_viewport_index_layer" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_KHR_maintenance3" ) + { + return "VK_VERSION_1_1"; + } + if ( extension == "VK_KHR_draw_indirect_count" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_EXT_global_priority" ) + { + return "VK_KHR_global_priority"; + } + if ( extension == "VK_KHR_shader_subgroup_extended_types" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_KHR_8bit_storage" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_KHR_shader_atomic_int64" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_EXT_calibrated_timestamps" ) + { + return "VK_KHR_calibrated_timestamps"; + } + if ( extension == "VK_EXT_vertex_attribute_divisor" ) + { + return "VK_KHR_vertex_attribute_divisor"; + } + if ( extension == "VK_EXT_pipeline_creation_feedback" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_KHR_driver_properties" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_KHR_shader_float_controls" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_KHR_depth_stencil_resolve" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_NV_fragment_shader_barycentric" ) + { + return "VK_KHR_fragment_shader_barycentric"; + } + if ( extension == "VK_KHR_timeline_semaphore" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_KHR_vulkan_memory_model" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_KHR_shader_terminate_invocation" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_EXT_scalar_block_layout" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_EXT_subgroup_size_control" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_KHR_spirv_1_4" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_KHR_separate_depth_stencil_layouts" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_EXT_tooling_info" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_EXT_separate_stencil_usage" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_KHR_uniform_buffer_standard_layout" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_KHR_buffer_device_address" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_EXT_line_rasterization" ) + { + return "VK_KHR_line_rasterization"; + } + if ( extension == "VK_EXT_host_query_reset" ) + { + return "VK_VERSION_1_2"; + } + if ( extension == "VK_EXT_index_type_uint8" ) + { + return "VK_KHR_index_type_uint8"; + } + if ( extension == "VK_EXT_extended_dynamic_state" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_EXT_shader_demote_to_helper_invocation" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_KHR_shader_integer_dot_product" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_EXT_texel_buffer_alignment" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_KHR_shader_non_semantic_info" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_EXT_private_data" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_EXT_pipeline_creation_cache_control" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_KHR_synchronization2" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_KHR_zero_initialize_workgroup_memory" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_EXT_ycbcr_2plane_444_formats" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_EXT_image_robustness" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_KHR_copy_commands2" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_EXT_4444_formats" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_ARM_rasterization_order_attachment_access" ) + { + return "VK_EXT_rasterization_order_attachment_access"; + } + if ( extension == "VK_VALVE_mutable_descriptor_type" ) + { + return "VK_EXT_mutable_descriptor_type"; + } + if ( extension == "VK_KHR_format_feature_flags2" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_EXT_extended_dynamic_state2" ) + { + return "VK_VERSION_1_3"; + } + if ( extension == "VK_EXT_global_priority_query" ) + { + return "VK_KHR_global_priority"; + } + if ( extension == "VK_EXT_load_store_op_none" ) + { + return "VK_KHR_load_store_op_none"; + } + if ( extension == "VK_KHR_maintenance4" ) + { + return "VK_VERSION_1_3"; + } + return ""; + } + + VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR_20 bool isDeprecatedExtension( std::string const & extension ) + { + return ( extension == "VK_EXT_debug_report" ) || ( extension == "VK_NV_glsl_shader" ) || ( extension == "VK_NV_dedicated_allocation" ) || + ( extension == "VK_AMD_gpu_shader_half_float" ) || ( extension == "VK_IMG_format_pvrtc" ) || ( extension == "VK_NV_external_memory_capabilities" ) || + ( extension == "VK_NV_external_memory" ) || +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + ( extension == "VK_NV_external_memory_win32" ) || +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + ( extension == "VK_EXT_validation_flags" ) || ( extension == "VK_EXT_shader_subgroup_ballot" ) || ( extension == "VK_EXT_shader_subgroup_vote" ) || +#if defined( VK_USE_PLATFORM_IOS_MVK ) + ( extension == "VK_MVK_ios_surface" ) || +#endif /*VK_USE_PLATFORM_IOS_MVK*/ +#if defined( VK_USE_PLATFORM_MACOS_MVK ) + ( extension == "VK_MVK_macos_surface" ) || +#endif /*VK_USE_PLATFORM_MACOS_MVK*/ + ( extension == "VK_AMD_gpu_shader_int16" ) || ( extension == "VK_EXT_buffer_device_address" ) || ( extension == "VK_EXT_validation_features" ); + } + + VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR_20 bool isDeviceExtension( std::string const & extension ) + { + return ( extension == "VK_KHR_swapchain" ) || ( extension == "VK_KHR_display_swapchain" ) || ( extension == "VK_NV_glsl_shader" ) || + ( extension == "VK_EXT_depth_range_unrestricted" ) || ( extension == "VK_KHR_sampler_mirror_clamp_to_edge" ) || + ( extension == "VK_IMG_filter_cubic" ) || ( extension == "VK_AMD_rasterization_order" ) || ( extension == "VK_AMD_shader_trinary_minmax" ) || + ( extension == "VK_AMD_shader_explicit_vertex_parameter" ) || ( extension == "VK_EXT_debug_marker" ) || ( extension == "VK_KHR_video_queue" ) || + ( extension == "VK_KHR_video_decode_queue" ) || ( extension == "VK_AMD_gcn_shader" ) || ( extension == "VK_NV_dedicated_allocation" ) || + ( extension == "VK_EXT_transform_feedback" ) || ( extension == "VK_NVX_binary_import" ) || ( extension == "VK_NVX_image_view_handle" ) || + ( extension == "VK_AMD_draw_indirect_count" ) || ( extension == "VK_AMD_negative_viewport_height" ) || + ( extension == "VK_AMD_gpu_shader_half_float" ) || ( extension == "VK_AMD_shader_ballot" ) || ( extension == "VK_KHR_video_encode_h264" ) || + ( extension == "VK_KHR_video_encode_h265" ) || ( extension == "VK_KHR_video_decode_h264" ) || ( extension == "VK_AMD_texture_gather_bias_lod" ) || + ( extension == "VK_AMD_shader_info" ) || ( extension == "VK_KHR_dynamic_rendering" ) || ( extension == "VK_AMD_shader_image_load_store_lod" ) || + ( extension == "VK_NV_corner_sampled_image" ) || ( extension == "VK_KHR_multiview" ) || ( extension == "VK_IMG_format_pvrtc" ) || + ( extension == "VK_NV_external_memory" ) +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + || ( extension == "VK_NV_external_memory_win32" ) || ( extension == "VK_NV_win32_keyed_mutex" ) +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + || ( extension == "VK_KHR_device_group" ) || ( extension == "VK_KHR_shader_draw_parameters" ) || ( extension == "VK_EXT_shader_subgroup_ballot" ) || + ( extension == "VK_EXT_shader_subgroup_vote" ) || ( extension == "VK_EXT_texture_compression_astc_hdr" ) || + ( extension == "VK_EXT_astc_decode_mode" ) || ( extension == "VK_EXT_pipeline_robustness" ) || ( extension == "VK_KHR_maintenance1" ) || + ( extension == "VK_KHR_external_memory" ) +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + || ( extension == "VK_KHR_external_memory_win32" ) +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + || ( extension == "VK_KHR_external_memory_fd" ) +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + || ( extension == "VK_KHR_win32_keyed_mutex" ) +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + || ( extension == "VK_KHR_external_semaphore" ) +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + || ( extension == "VK_KHR_external_semaphore_win32" ) +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + || ( extension == "VK_KHR_external_semaphore_fd" ) || ( extension == "VK_KHR_push_descriptor" ) || ( extension == "VK_EXT_conditional_rendering" ) || + ( extension == "VK_KHR_shader_float16_int8" ) || ( extension == "VK_KHR_16bit_storage" ) || ( extension == "VK_KHR_incremental_present" ) || + ( extension == "VK_KHR_descriptor_update_template" ) || ( extension == "VK_NV_clip_space_w_scaling" ) || ( extension == "VK_EXT_display_control" ) || + ( extension == "VK_GOOGLE_display_timing" ) || ( extension == "VK_NV_sample_mask_override_coverage" ) || + ( extension == "VK_NV_geometry_shader_passthrough" ) || ( extension == "VK_NV_viewport_array2" ) || + ( extension == "VK_NVX_multiview_per_view_attributes" ) || ( extension == "VK_NV_viewport_swizzle" ) || + ( extension == "VK_EXT_discard_rectangles" ) || ( extension == "VK_EXT_conservative_rasterization" ) || + ( extension == "VK_EXT_depth_clip_enable" ) || ( extension == "VK_EXT_hdr_metadata" ) || ( extension == "VK_KHR_imageless_framebuffer" ) || + ( extension == "VK_KHR_create_renderpass2" ) || ( extension == "VK_IMG_relaxed_line_rasterization" ) || + ( extension == "VK_KHR_shared_presentable_image" ) || ( extension == "VK_KHR_external_fence" ) +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + || ( extension == "VK_KHR_external_fence_win32" ) +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + || ( extension == "VK_KHR_external_fence_fd" ) || ( extension == "VK_KHR_performance_query" ) || ( extension == "VK_KHR_maintenance2" ) || + ( extension == "VK_KHR_variable_pointers" ) || ( extension == "VK_EXT_external_memory_dma_buf" ) || ( extension == "VK_EXT_queue_family_foreign" ) || + ( extension == "VK_KHR_dedicated_allocation" ) +#if defined( VK_USE_PLATFORM_ANDROID_KHR ) + || ( extension == "VK_ANDROID_external_memory_android_hardware_buffer" ) +#endif /*VK_USE_PLATFORM_ANDROID_KHR*/ + || ( extension == "VK_EXT_sampler_filter_minmax" ) || ( extension == "VK_KHR_storage_buffer_storage_class" ) || + ( extension == "VK_AMD_gpu_shader_int16" ) +#if defined( VK_ENABLE_BETA_EXTENSIONS ) + || ( extension == "VK_AMDX_shader_enqueue" ) +#endif /*VK_ENABLE_BETA_EXTENSIONS*/ + || ( extension == "VK_AMD_mixed_attachment_samples" ) || ( extension == "VK_AMD_shader_fragment_mask" ) || + ( extension == "VK_EXT_inline_uniform_block" ) || ( extension == "VK_EXT_shader_stencil_export" ) || ( extension == "VK_EXT_sample_locations" ) || + ( extension == "VK_KHR_relaxed_block_layout" ) || ( extension == "VK_KHR_get_memory_requirements2" ) || + ( extension == "VK_KHR_image_format_list" ) || ( extension == "VK_EXT_blend_operation_advanced" ) || + ( extension == "VK_NV_fragment_coverage_to_color" ) || ( extension == "VK_KHR_acceleration_structure" ) || + ( extension == "VK_KHR_ray_tracing_pipeline" ) || ( extension == "VK_KHR_ray_query" ) || ( extension == "VK_NV_framebuffer_mixed_samples" ) || + ( extension == "VK_NV_fill_rectangle" ) || ( extension == "VK_NV_shader_sm_builtins" ) || ( extension == "VK_EXT_post_depth_coverage" ) || + ( extension == "VK_KHR_sampler_ycbcr_conversion" ) || ( extension == "VK_KHR_bind_memory2" ) || + ( extension == "VK_EXT_image_drm_format_modifier" ) || ( extension == "VK_EXT_validation_cache" ) || ( extension == "VK_EXT_descriptor_indexing" ) || + ( extension == "VK_EXT_shader_viewport_index_layer" ) +#if defined( VK_ENABLE_BETA_EXTENSIONS ) + || ( extension == "VK_KHR_portability_subset" ) +#endif /*VK_ENABLE_BETA_EXTENSIONS*/ + || ( extension == "VK_NV_shading_rate_image" ) || ( extension == "VK_NV_ray_tracing" ) || ( extension == "VK_NV_representative_fragment_test" ) || + ( extension == "VK_KHR_maintenance3" ) || ( extension == "VK_KHR_draw_indirect_count" ) || ( extension == "VK_EXT_filter_cubic" ) || + ( extension == "VK_QCOM_render_pass_shader_resolve" ) || ( extension == "VK_EXT_global_priority" ) || + ( extension == "VK_KHR_shader_subgroup_extended_types" ) || ( extension == "VK_KHR_8bit_storage" ) || + ( extension == "VK_EXT_external_memory_host" ) || ( extension == "VK_AMD_buffer_marker" ) || ( extension == "VK_KHR_shader_atomic_int64" ) || + ( extension == "VK_KHR_shader_clock" ) || ( extension == "VK_AMD_pipeline_compiler_control" ) || ( extension == "VK_EXT_calibrated_timestamps" ) || + ( extension == "VK_AMD_shader_core_properties" ) || ( extension == "VK_KHR_video_decode_h265" ) || ( extension == "VK_KHR_global_priority" ) || + ( extension == "VK_AMD_memory_overallocation_behavior" ) || ( extension == "VK_EXT_vertex_attribute_divisor" ) +#if defined( VK_USE_PLATFORM_GGP ) + || ( extension == "VK_GGP_frame_token" ) +#endif /*VK_USE_PLATFORM_GGP*/ + || ( extension == "VK_EXT_pipeline_creation_feedback" ) || ( extension == "VK_KHR_driver_properties" ) || + ( extension == "VK_KHR_shader_float_controls" ) || ( extension == "VK_NV_shader_subgroup_partitioned" ) || + ( extension == "VK_KHR_depth_stencil_resolve" ) || ( extension == "VK_KHR_swapchain_mutable_format" ) || + ( extension == "VK_NV_compute_shader_derivatives" ) || ( extension == "VK_NV_mesh_shader" ) || + ( extension == "VK_NV_fragment_shader_barycentric" ) || ( extension == "VK_NV_shader_image_footprint" ) || + ( extension == "VK_NV_scissor_exclusive" ) || ( extension == "VK_NV_device_diagnostic_checkpoints" ) || + ( extension == "VK_KHR_timeline_semaphore" ) || ( extension == "VK_INTEL_shader_integer_functions2" ) || + ( extension == "VK_INTEL_performance_query" ) || ( extension == "VK_KHR_vulkan_memory_model" ) || ( extension == "VK_EXT_pci_bus_info" ) || + ( extension == "VK_AMD_display_native_hdr" ) || ( extension == "VK_KHR_shader_terminate_invocation" ) || + ( extension == "VK_EXT_fragment_density_map" ) || ( extension == "VK_EXT_scalar_block_layout" ) || + ( extension == "VK_GOOGLE_hlsl_functionality1" ) || ( extension == "VK_GOOGLE_decorate_string" ) || + ( extension == "VK_EXT_subgroup_size_control" ) || ( extension == "VK_KHR_fragment_shading_rate" ) || + ( extension == "VK_AMD_shader_core_properties2" ) || ( extension == "VK_AMD_device_coherent_memory" ) || + ( extension == "VK_KHR_dynamic_rendering_local_read" ) || ( extension == "VK_EXT_shader_image_atomic_int64" ) || + ( extension == "VK_KHR_shader_quad_control" ) || ( extension == "VK_KHR_spirv_1_4" ) || ( extension == "VK_EXT_memory_budget" ) || + ( extension == "VK_EXT_memory_priority" ) || ( extension == "VK_NV_dedicated_allocation_image_aliasing" ) || + ( extension == "VK_KHR_separate_depth_stencil_layouts" ) || ( extension == "VK_EXT_buffer_device_address" ) || + ( extension == "VK_EXT_tooling_info" ) || ( extension == "VK_EXT_separate_stencil_usage" ) || ( extension == "VK_KHR_present_wait" ) || + ( extension == "VK_NV_cooperative_matrix" ) || ( extension == "VK_NV_coverage_reduction_mode" ) || + ( extension == "VK_EXT_fragment_shader_interlock" ) || ( extension == "VK_EXT_ycbcr_image_arrays" ) || + ( extension == "VK_KHR_uniform_buffer_standard_layout" ) || ( extension == "VK_EXT_provoking_vertex" ) +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + || ( extension == "VK_EXT_full_screen_exclusive" ) +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + || ( extension == "VK_KHR_buffer_device_address" ) || ( extension == "VK_EXT_line_rasterization" ) || ( extension == "VK_EXT_shader_atomic_float" ) || + ( extension == "VK_EXT_host_query_reset" ) || ( extension == "VK_EXT_index_type_uint8" ) || ( extension == "VK_EXT_extended_dynamic_state" ) || + ( extension == "VK_KHR_deferred_host_operations" ) || ( extension == "VK_KHR_pipeline_executable_properties" ) || + ( extension == "VK_EXT_host_image_copy" ) || ( extension == "VK_KHR_map_memory2" ) || ( extension == "VK_EXT_map_memory_placed" ) || + ( extension == "VK_EXT_shader_atomic_float2" ) || ( extension == "VK_EXT_swapchain_maintenance1" ) || + ( extension == "VK_EXT_shader_demote_to_helper_invocation" ) || ( extension == "VK_NV_device_generated_commands" ) || + ( extension == "VK_NV_inherited_viewport_scissor" ) || ( extension == "VK_KHR_shader_integer_dot_product" ) || + ( extension == "VK_EXT_texel_buffer_alignment" ) || ( extension == "VK_QCOM_render_pass_transform" ) || + ( extension == "VK_EXT_depth_bias_control" ) || ( extension == "VK_EXT_device_memory_report" ) || ( extension == "VK_EXT_robustness2" ) || + ( extension == "VK_EXT_custom_border_color" ) || ( extension == "VK_GOOGLE_user_type" ) || ( extension == "VK_KHR_pipeline_library" ) || + ( extension == "VK_NV_present_barrier" ) || ( extension == "VK_KHR_shader_non_semantic_info" ) || ( extension == "VK_KHR_present_id" ) || + ( extension == "VK_EXT_private_data" ) || ( extension == "VK_EXT_pipeline_creation_cache_control" ) || + ( extension == "VK_KHR_video_encode_queue" ) || ( extension == "VK_NV_device_diagnostics_config" ) || + ( extension == "VK_QCOM_render_pass_store_ops" ) +#if defined( VK_ENABLE_BETA_EXTENSIONS ) + || ( extension == "VK_NV_cuda_kernel_launch" ) +#endif /*VK_ENABLE_BETA_EXTENSIONS*/ + || ( extension == "VK_NV_low_latency" ) +#if defined( VK_USE_PLATFORM_METAL_EXT ) + || ( extension == "VK_EXT_metal_objects" ) +#endif /*VK_USE_PLATFORM_METAL_EXT*/ + || ( extension == "VK_KHR_synchronization2" ) || ( extension == "VK_EXT_descriptor_buffer" ) || ( extension == "VK_EXT_graphics_pipeline_library" ) || + ( extension == "VK_AMD_shader_early_and_late_fragment_tests" ) || ( extension == "VK_KHR_fragment_shader_barycentric" ) || + ( extension == "VK_KHR_shader_subgroup_uniform_control_flow" ) || ( extension == "VK_KHR_zero_initialize_workgroup_memory" ) || + ( extension == "VK_NV_fragment_shading_rate_enums" ) || ( extension == "VK_NV_ray_tracing_motion_blur" ) || ( extension == "VK_EXT_mesh_shader" ) || + ( extension == "VK_EXT_ycbcr_2plane_444_formats" ) || ( extension == "VK_EXT_fragment_density_map2" ) || + ( extension == "VK_QCOM_rotated_copy_commands" ) || ( extension == "VK_EXT_image_robustness" ) || + ( extension == "VK_KHR_workgroup_memory_explicit_layout" ) || ( extension == "VK_KHR_copy_commands2" ) || + ( extension == "VK_EXT_image_compression_control" ) || ( extension == "VK_EXT_attachment_feedback_loop_layout" ) || + ( extension == "VK_EXT_4444_formats" ) || ( extension == "VK_EXT_device_fault" ) || + ( extension == "VK_ARM_rasterization_order_attachment_access" ) || ( extension == "VK_EXT_rgba10x6_formats" ) +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + || ( extension == "VK_NV_acquire_winrt_display" ) +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + || ( extension == "VK_VALVE_mutable_descriptor_type" ) || ( extension == "VK_EXT_vertex_input_dynamic_state" ) || + ( extension == "VK_EXT_physical_device_drm" ) || ( extension == "VK_EXT_device_address_binding_report" ) || + ( extension == "VK_EXT_depth_clip_control" ) || ( extension == "VK_EXT_primitive_topology_list_restart" ) || + ( extension == "VK_KHR_format_feature_flags2" ) +#if defined( VK_USE_PLATFORM_FUCHSIA ) + || ( extension == "VK_FUCHSIA_external_memory" ) || ( extension == "VK_FUCHSIA_external_semaphore" ) || ( extension == "VK_FUCHSIA_buffer_collection" ) +#endif /*VK_USE_PLATFORM_FUCHSIA*/ + || ( extension == "VK_HUAWEI_subpass_shading" ) || ( extension == "VK_HUAWEI_invocation_mask" ) || ( extension == "VK_NV_external_memory_rdma" ) || + ( extension == "VK_EXT_pipeline_properties" ) || ( extension == "VK_EXT_frame_boundary" ) || + ( extension == "VK_EXT_multisampled_render_to_single_sampled" ) || ( extension == "VK_EXT_extended_dynamic_state2" ) || + ( extension == "VK_EXT_color_write_enable" ) || ( extension == "VK_EXT_primitives_generated_query" ) || + ( extension == "VK_KHR_ray_tracing_maintenance1" ) || ( extension == "VK_EXT_global_priority_query" ) || + ( extension == "VK_EXT_image_view_min_lod" ) || ( extension == "VK_EXT_multi_draw" ) || ( extension == "VK_EXT_image_2d_view_of_3d" ) || + ( extension == "VK_EXT_shader_tile_image" ) || ( extension == "VK_EXT_opacity_micromap" ) +#if defined( VK_ENABLE_BETA_EXTENSIONS ) + || ( extension == "VK_NV_displacement_micromap" ) +#endif /*VK_ENABLE_BETA_EXTENSIONS*/ + || ( extension == "VK_EXT_load_store_op_none" ) || ( extension == "VK_HUAWEI_cluster_culling_shader" ) || + ( extension == "VK_EXT_border_color_swizzle" ) || ( extension == "VK_EXT_pageable_device_local_memory" ) || ( extension == "VK_KHR_maintenance4" ) || + ( extension == "VK_ARM_shader_core_properties" ) || ( extension == "VK_KHR_shader_subgroup_rotate" ) || + ( extension == "VK_ARM_scheduling_controls" ) || ( extension == "VK_EXT_image_sliced_view_of_3d" ) || + ( extension == "VK_VALVE_descriptor_set_host_mapping" ) || ( extension == "VK_EXT_depth_clamp_zero_one" ) || + ( extension == "VK_EXT_non_seamless_cube_map" ) || ( extension == "VK_ARM_render_pass_striped" ) || + ( extension == "VK_QCOM_fragment_density_map_offset" ) || ( extension == "VK_NV_copy_memory_indirect" ) || + ( extension == "VK_NV_memory_decompression" ) || ( extension == "VK_NV_device_generated_commands_compute" ) || + ( extension == "VK_NV_linear_color_attachment" ) || ( extension == "VK_KHR_shader_maximal_reconvergence" ) || + ( extension == "VK_EXT_image_compression_control_swapchain" ) || ( extension == "VK_QCOM_image_processing" ) || + ( extension == "VK_EXT_nested_command_buffer" ) || ( extension == "VK_EXT_external_memory_acquire_unmodified" ) || + ( extension == "VK_EXT_extended_dynamic_state3" ) || ( extension == "VK_EXT_subpass_merge_feedback" ) || + ( extension == "VK_EXT_shader_module_identifier" ) || ( extension == "VK_EXT_rasterization_order_attachment_access" ) || + ( extension == "VK_NV_optical_flow" ) || ( extension == "VK_EXT_legacy_dithering" ) || ( extension == "VK_EXT_pipeline_protected_access" ) +#if defined( VK_USE_PLATFORM_ANDROID_KHR ) + || ( extension == "VK_ANDROID_external_format_resolve" ) +#endif /*VK_USE_PLATFORM_ANDROID_KHR*/ + || ( extension == "VK_KHR_maintenance5" ) || ( extension == "VK_KHR_ray_tracing_position_fetch" ) || ( extension == "VK_EXT_shader_object" ) || + ( extension == "VK_QCOM_tile_properties" ) || ( extension == "VK_SEC_amigo_profiling" ) || ( extension == "VK_QCOM_multiview_per_view_viewports" ) || + ( extension == "VK_NV_ray_tracing_invocation_reorder" ) || ( extension == "VK_NV_extended_sparse_address_space" ) || + ( extension == "VK_EXT_mutable_descriptor_type" ) || ( extension == "VK_ARM_shader_core_builtins" ) || + ( extension == "VK_EXT_pipeline_library_group_handles" ) || ( extension == "VK_EXT_dynamic_rendering_unused_attachments" ) || + ( extension == "VK_NV_low_latency2" ) || ( extension == "VK_KHR_cooperative_matrix" ) || + ( extension == "VK_QCOM_multiview_per_view_render_areas" ) || ( extension == "VK_KHR_video_decode_av1" ) || + ( extension == "VK_KHR_video_maintenance1" ) || ( extension == "VK_NV_per_stage_descriptor_set" ) || ( extension == "VK_QCOM_image_processing2" ) || + ( extension == "VK_QCOM_filter_cubic_weights" ) || ( extension == "VK_QCOM_ycbcr_degamma" ) || ( extension == "VK_QCOM_filter_cubic_clamp" ) || + ( extension == "VK_EXT_attachment_feedback_loop_dynamic_state" ) || ( extension == "VK_KHR_vertex_attribute_divisor" ) || + ( extension == "VK_KHR_load_store_op_none" ) || ( extension == "VK_KHR_shader_float_controls2" ) +#if defined( VK_USE_PLATFORM_SCREEN_QNX ) + || ( extension == "VK_QNX_external_memory_screen_buffer" ) +#endif /*VK_USE_PLATFORM_SCREEN_QNX*/ + || ( extension == "VK_MSFT_layered_driver" ) || ( extension == "VK_KHR_index_type_uint8" ) || ( extension == "VK_KHR_line_rasterization" ) || + ( extension == "VK_KHR_calibrated_timestamps" ) || ( extension == "VK_KHR_shader_expect_assume" ) || ( extension == "VK_KHR_maintenance6" ) || + ( extension == "VK_NV_descriptor_pool_overallocation" ) || ( extension == "VK_NV_raw_access_chains" ) || + ( extension == "VK_NV_shader_atomic_float16_vector" ) || ( extension == "VK_NV_ray_tracing_validation" ); + } + + VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR_20 bool isInstanceExtension( std::string const & extension ) + { + return ( extension == "VK_KHR_surface" ) || ( extension == "VK_KHR_display" ) +#if defined( VK_USE_PLATFORM_XLIB_KHR ) + || ( extension == "VK_KHR_xlib_surface" ) +#endif /*VK_USE_PLATFORM_XLIB_KHR*/ +#if defined( VK_USE_PLATFORM_XCB_KHR ) + || ( extension == "VK_KHR_xcb_surface" ) +#endif /*VK_USE_PLATFORM_XCB_KHR*/ +#if defined( VK_USE_PLATFORM_WAYLAND_KHR ) + || ( extension == "VK_KHR_wayland_surface" ) +#endif /*VK_USE_PLATFORM_WAYLAND_KHR*/ +#if defined( VK_USE_PLATFORM_ANDROID_KHR ) + || ( extension == "VK_KHR_android_surface" ) +#endif /*VK_USE_PLATFORM_ANDROID_KHR*/ +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + || ( extension == "VK_KHR_win32_surface" ) +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + || ( extension == "VK_EXT_debug_report" ) +#if defined( VK_USE_PLATFORM_GGP ) + || ( extension == "VK_GGP_stream_descriptor_surface" ) +#endif /*VK_USE_PLATFORM_GGP*/ + || ( extension == "VK_NV_external_memory_capabilities" ) || ( extension == "VK_KHR_get_physical_device_properties2" ) || + ( extension == "VK_EXT_validation_flags" ) +#if defined( VK_USE_PLATFORM_VI_NN ) + || ( extension == "VK_NN_vi_surface" ) +#endif /*VK_USE_PLATFORM_VI_NN*/ + || ( extension == "VK_KHR_device_group_creation" ) || ( extension == "VK_KHR_external_memory_capabilities" ) || + ( extension == "VK_KHR_external_semaphore_capabilities" ) || ( extension == "VK_EXT_direct_mode_display" ) +#if defined( VK_USE_PLATFORM_XLIB_XRANDR_EXT ) + || ( extension == "VK_EXT_acquire_xlib_display" ) +#endif /*VK_USE_PLATFORM_XLIB_XRANDR_EXT*/ + || ( extension == "VK_EXT_display_surface_counter" ) || ( extension == "VK_EXT_swapchain_colorspace" ) || + ( extension == "VK_KHR_external_fence_capabilities" ) || ( extension == "VK_KHR_get_surface_capabilities2" ) || + ( extension == "VK_KHR_get_display_properties2" ) +#if defined( VK_USE_PLATFORM_IOS_MVK ) + || ( extension == "VK_MVK_ios_surface" ) +#endif /*VK_USE_PLATFORM_IOS_MVK*/ +#if defined( VK_USE_PLATFORM_MACOS_MVK ) + || ( extension == "VK_MVK_macos_surface" ) +#endif /*VK_USE_PLATFORM_MACOS_MVK*/ + || ( extension == "VK_EXT_debug_utils" ) +#if defined( VK_USE_PLATFORM_FUCHSIA ) + || ( extension == "VK_FUCHSIA_imagepipe_surface" ) +#endif /*VK_USE_PLATFORM_FUCHSIA*/ +#if defined( VK_USE_PLATFORM_METAL_EXT ) + || ( extension == "VK_EXT_metal_surface" ) +#endif /*VK_USE_PLATFORM_METAL_EXT*/ + || ( extension == "VK_KHR_surface_protected_capabilities" ) || ( extension == "VK_EXT_validation_features" ) || + ( extension == "VK_EXT_headless_surface" ) || ( extension == "VK_EXT_surface_maintenance1" ) || ( extension == "VK_EXT_acquire_drm_display" ) +#if defined( VK_USE_PLATFORM_DIRECTFB_EXT ) + || ( extension == "VK_EXT_directfb_surface" ) +#endif /*VK_USE_PLATFORM_DIRECTFB_EXT*/ +#if defined( VK_USE_PLATFORM_SCREEN_QNX ) + || ( extension == "VK_QNX_screen_surface" ) +#endif /*VK_USE_PLATFORM_SCREEN_QNX*/ + || ( extension == "VK_KHR_portability_enumeration" ) || ( extension == "VK_GOOGLE_surfaceless_query" ) || + ( extension == "VK_LUNARG_direct_driver_loading" ) || ( extension == "VK_EXT_layer_settings" ); + } + + VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR_20 bool isObsoletedExtension( std::string const & extension ) + { + return ( extension == "VK_AMD_negative_viewport_height" ); + } + + VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR_20 bool isPromotedExtension( std::string const & extension ) + { + return ( extension == "VK_KHR_sampler_mirror_clamp_to_edge" ) || ( extension == "VK_EXT_debug_marker" ) || ( extension == "VK_AMD_draw_indirect_count" ) || + ( extension == "VK_KHR_dynamic_rendering" ) || ( extension == "VK_KHR_multiview" ) || +#if defined( VK_USE_PLATFORM_WIN32_KHR ) + ( extension == "VK_NV_win32_keyed_mutex" ) || +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + ( extension == "VK_KHR_get_physical_device_properties2" ) || ( extension == "VK_KHR_device_group" ) || + ( extension == "VK_KHR_shader_draw_parameters" ) || ( extension == "VK_EXT_texture_compression_astc_hdr" ) || + ( extension == "VK_KHR_maintenance1" ) || ( extension == "VK_KHR_device_group_creation" ) || + ( extension == "VK_KHR_external_memory_capabilities" ) || ( extension == "VK_KHR_external_memory" ) || + ( extension == "VK_KHR_external_semaphore_capabilities" ) || ( extension == "VK_KHR_external_semaphore" ) || + ( extension == "VK_KHR_shader_float16_int8" ) || ( extension == "VK_KHR_16bit_storage" ) || ( extension == "VK_KHR_descriptor_update_template" ) || + ( extension == "VK_KHR_imageless_framebuffer" ) || ( extension == "VK_KHR_create_renderpass2" ) || + ( extension == "VK_KHR_external_fence_capabilities" ) || ( extension == "VK_KHR_external_fence" ) || ( extension == "VK_KHR_maintenance2" ) || + ( extension == "VK_KHR_variable_pointers" ) || ( extension == "VK_KHR_dedicated_allocation" ) || ( extension == "VK_EXT_sampler_filter_minmax" ) || + ( extension == "VK_KHR_storage_buffer_storage_class" ) || ( extension == "VK_EXT_inline_uniform_block" ) || + ( extension == "VK_KHR_relaxed_block_layout" ) || ( extension == "VK_KHR_get_memory_requirements2" ) || + ( extension == "VK_KHR_image_format_list" ) || ( extension == "VK_KHR_sampler_ycbcr_conversion" ) || ( extension == "VK_KHR_bind_memory2" ) || + ( extension == "VK_EXT_descriptor_indexing" ) || ( extension == "VK_EXT_shader_viewport_index_layer" ) || ( extension == "VK_KHR_maintenance3" ) || + ( extension == "VK_KHR_draw_indirect_count" ) || ( extension == "VK_EXT_global_priority" ) || + ( extension == "VK_KHR_shader_subgroup_extended_types" ) || ( extension == "VK_KHR_8bit_storage" ) || + ( extension == "VK_KHR_shader_atomic_int64" ) || ( extension == "VK_EXT_calibrated_timestamps" ) || + ( extension == "VK_EXT_vertex_attribute_divisor" ) || ( extension == "VK_EXT_pipeline_creation_feedback" ) || + ( extension == "VK_KHR_driver_properties" ) || ( extension == "VK_KHR_shader_float_controls" ) || ( extension == "VK_KHR_depth_stencil_resolve" ) || + ( extension == "VK_NV_fragment_shader_barycentric" ) || ( extension == "VK_KHR_timeline_semaphore" ) || + ( extension == "VK_KHR_vulkan_memory_model" ) || ( extension == "VK_KHR_shader_terminate_invocation" ) || + ( extension == "VK_EXT_scalar_block_layout" ) || ( extension == "VK_EXT_subgroup_size_control" ) || ( extension == "VK_KHR_spirv_1_4" ) || + ( extension == "VK_KHR_separate_depth_stencil_layouts" ) || ( extension == "VK_EXT_tooling_info" ) || + ( extension == "VK_EXT_separate_stencil_usage" ) || ( extension == "VK_KHR_uniform_buffer_standard_layout" ) || + ( extension == "VK_KHR_buffer_device_address" ) || ( extension == "VK_EXT_line_rasterization" ) || ( extension == "VK_EXT_host_query_reset" ) || + ( extension == "VK_EXT_index_type_uint8" ) || ( extension == "VK_EXT_extended_dynamic_state" ) || + ( extension == "VK_EXT_shader_demote_to_helper_invocation" ) || ( extension == "VK_KHR_shader_integer_dot_product" ) || + ( extension == "VK_EXT_texel_buffer_alignment" ) || ( extension == "VK_KHR_shader_non_semantic_info" ) || ( extension == "VK_EXT_private_data" ) || + ( extension == "VK_EXT_pipeline_creation_cache_control" ) || ( extension == "VK_KHR_synchronization2" ) || + ( extension == "VK_KHR_zero_initialize_workgroup_memory" ) || ( extension == "VK_EXT_ycbcr_2plane_444_formats" ) || + ( extension == "VK_EXT_image_robustness" ) || ( extension == "VK_KHR_copy_commands2" ) || ( extension == "VK_EXT_4444_formats" ) || + ( extension == "VK_ARM_rasterization_order_attachment_access" ) || ( extension == "VK_VALVE_mutable_descriptor_type" ) || + ( extension == "VK_KHR_format_feature_flags2" ) || ( extension == "VK_EXT_extended_dynamic_state2" ) || + ( extension == "VK_EXT_global_priority_query" ) || ( extension == "VK_EXT_load_store_op_none" ) || ( extension == "VK_KHR_maintenance4" ); + } +} // namespace VULKAN_HPP_NAMESPACE + +#endif diff --git a/external/vulkan/vulkan_format_traits.hpp b/external/vulkan/vulkan_format_traits.hpp new file mode 100644 index 0000000..8f26981 Binary files /dev/null and b/external/vulkan/vulkan_format_traits.hpp differ diff --git a/external/vulkan/vulkan_fuchsia.h b/external/vulkan/vulkan_fuchsia.h index 61774ff..f60907d 100644 --- a/external/vulkan/vulkan_fuchsia.h +++ b/external/vulkan/vulkan_fuchsia.h @@ -2,7 +2,7 @@ #define VULKAN_FUCHSIA_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ extern "C" { +// VK_FUCHSIA_imagepipe_surface is a preprocessor guard. Do not pass it to API calls. #define VK_FUCHSIA_imagepipe_surface 1 #define VK_FUCHSIA_IMAGEPIPE_SURFACE_SPEC_VERSION 1 #define VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME "VK_FUCHSIA_imagepipe_surface" @@ -41,6 +42,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateImagePipeSurfaceFUCHSIA( #endif +// VK_FUCHSIA_external_memory is a preprocessor guard. Do not pass it to API calls. #define VK_FUCHSIA_external_memory 1 #define VK_FUCHSIA_EXTERNAL_MEMORY_SPEC_VERSION 1 #define VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME "VK_FUCHSIA_external_memory" @@ -81,6 +83,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandlePropertiesFUCHSIA( #endif +// VK_FUCHSIA_external_semaphore is a preprocessor guard. Do not pass it to API calls. #define VK_FUCHSIA_external_semaphore 1 #define VK_FUCHSIA_EXTERNAL_SEMAPHORE_SPEC_VERSION 1 #define VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_FUCHSIA_external_semaphore" @@ -115,6 +118,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreZirconHandleFUCHSIA( #endif +// VK_FUCHSIA_buffer_collection is a preprocessor guard. Do not pass it to API calls. #define VK_FUCHSIA_buffer_collection 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferCollectionFUCHSIA) #define VK_FUCHSIA_BUFFER_COLLECTION_SPEC_VERSION 2 diff --git a/external/vulkan/vulkan_funcs.hpp b/external/vulkan/vulkan_funcs.hpp new file mode 100644 index 0000000..86a4863 Binary files /dev/null and b/external/vulkan/vulkan_funcs.hpp differ diff --git a/external/vulkan/vulkan_ggp.h b/external/vulkan/vulkan_ggp.h index 19dfd22..0a8863a 100644 --- a/external/vulkan/vulkan_ggp.h +++ b/external/vulkan/vulkan_ggp.h @@ -2,7 +2,7 @@ #define VULKAN_GGP_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ extern "C" { +// VK_GGP_stream_descriptor_surface is a preprocessor guard. Do not pass it to API calls. #define VK_GGP_stream_descriptor_surface 1 #define VK_GGP_STREAM_DESCRIPTOR_SURFACE_SPEC_VERSION 1 #define VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME "VK_GGP_stream_descriptor_surface" @@ -41,6 +42,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateStreamDescriptorSurfaceGGP( #endif +// VK_GGP_frame_token is a preprocessor guard. Do not pass it to API calls. #define VK_GGP_frame_token 1 #define VK_GGP_FRAME_TOKEN_SPEC_VERSION 1 #define VK_GGP_FRAME_TOKEN_EXTENSION_NAME "VK_GGP_frame_token" diff --git a/external/vulkan/vulkan_handles.hpp b/external/vulkan/vulkan_handles.hpp new file mode 100644 index 0000000..4208b8c Binary files /dev/null and b/external/vulkan/vulkan_handles.hpp differ diff --git a/external/vulkan/vulkan_hash.hpp b/external/vulkan/vulkan_hash.hpp new file mode 100644 index 0000000..8adf257 Binary files /dev/null and b/external/vulkan/vulkan_hash.hpp differ diff --git a/external/vulkan/vulkan_hpp_macros.hpp b/external/vulkan/vulkan_hpp_macros.hpp new file mode 100644 index 0000000..b754679 --- /dev/null +++ b/external/vulkan/vulkan_hpp_macros.hpp @@ -0,0 +1,298 @@ +// Copyright 2015-2024 The Khronos Group Inc. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT +// + +// This header is generated from the Khronos Vulkan XML API Registry. + +#ifndef VULKAN_HPP_MACROS_HPP +#define VULKAN_HPP_MACROS_HPP + +#if defined( _MSVC_LANG ) +# define VULKAN_HPP_CPLUSPLUS _MSVC_LANG +#else +# define VULKAN_HPP_CPLUSPLUS __cplusplus +#endif + +#if 202002L < VULKAN_HPP_CPLUSPLUS +# define VULKAN_HPP_CPP_VERSION 23 +#elif 201703L < VULKAN_HPP_CPLUSPLUS +# define VULKAN_HPP_CPP_VERSION 20 +#elif 201402L < VULKAN_HPP_CPLUSPLUS +# define VULKAN_HPP_CPP_VERSION 17 +#elif 201103L < VULKAN_HPP_CPLUSPLUS +# define VULKAN_HPP_CPP_VERSION 14 +#elif 199711L < VULKAN_HPP_CPLUSPLUS +# define VULKAN_HPP_CPP_VERSION 11 +#else +# error "vulkan.hpp needs at least c++ standard version 11" +#endif + +// include headers holding feature-test macros +#if 20 <= VULKAN_HPP_CPP_VERSION +# include +#else +# include +#endif + +#if defined( VULKAN_HPP_DISABLE_ENHANCED_MODE ) +# if !defined( VULKAN_HPP_NO_SMART_HANDLE ) +# define VULKAN_HPP_NO_SMART_HANDLE +# endif +#endif + +#if defined( VULKAN_HPP_NO_CONSTRUCTORS ) +# if !defined( VULKAN_HPP_NO_STRUCT_CONSTRUCTORS ) +# define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS +# endif +# if !defined( VULKAN_HPP_NO_UNION_CONSTRUCTORS ) +# define VULKAN_HPP_NO_UNION_CONSTRUCTORS +# endif +#endif + +#if defined( VULKAN_HPP_NO_SETTERS ) +# if !defined( VULKAN_HPP_NO_STRUCT_SETTERS ) +# define VULKAN_HPP_NO_STRUCT_SETTERS +# endif +# if !defined( VULKAN_HPP_NO_UNION_SETTERS ) +# define VULKAN_HPP_NO_UNION_SETTERS +# endif +#endif + +#if !defined( VULKAN_HPP_ASSERT ) +# define VULKAN_HPP_ASSERT assert +#endif + +#if !defined( VULKAN_HPP_ASSERT_ON_RESULT ) +# define VULKAN_HPP_ASSERT_ON_RESULT VULKAN_HPP_ASSERT +#endif + +#if !defined( VULKAN_HPP_STATIC_ASSERT ) +# define VULKAN_HPP_STATIC_ASSERT static_assert +#endif + +#if !defined( VULKAN_HPP_ENABLE_DYNAMIC_LOADER_TOOL ) +# define VULKAN_HPP_ENABLE_DYNAMIC_LOADER_TOOL 1 +#endif + +#if !defined( __has_include ) +# define __has_include( x ) false +#endif + +#if ( 201907 <= __cpp_lib_three_way_comparison ) && __has_include( ) && !defined( VULKAN_HPP_NO_SPACESHIP_OPERATOR ) +# define VULKAN_HPP_HAS_SPACESHIP_OPERATOR +#endif + +#if ( 201803 <= __cpp_lib_span ) +# define VULKAN_HPP_SUPPORT_SPAN +#endif + +// 32-bit vulkan is not typesafe for non-dispatchable handles, so don't allow copy constructors on this platform by default. +// To enable this feature on 32-bit platforms please #define VULKAN_HPP_TYPESAFE_CONVERSION 1 +// To disable this feature on 64-bit platforms please #define VULKAN_HPP_TYPESAFE_CONVERSION 0 +#if ( VK_USE_64_BIT_PTR_DEFINES == 1 ) +# if !defined( VULKAN_HPP_TYPESAFE_CONVERSION ) +# define VULKAN_HPP_TYPESAFE_CONVERSION 1 +# endif +#endif + +#if defined( __GNUC__ ) +# define GCC_VERSION ( __GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ ) +#endif + +#if !defined( VULKAN_HPP_HAS_UNRESTRICTED_UNIONS ) +# if defined( __clang__ ) +# if __has_feature( cxx_unrestricted_unions ) +# define VULKAN_HPP_HAS_UNRESTRICTED_UNIONS +# endif +# elif defined( __GNUC__ ) +# if 40600 <= GCC_VERSION +# define VULKAN_HPP_HAS_UNRESTRICTED_UNIONS +# endif +# elif defined( _MSC_VER ) +# if 1900 <= _MSC_VER +# define VULKAN_HPP_HAS_UNRESTRICTED_UNIONS +# endif +# endif +#endif + +#if !defined( VULKAN_HPP_INLINE ) +# if defined( __clang__ ) +# if __has_attribute( always_inline ) +# define VULKAN_HPP_INLINE __attribute__( ( always_inline ) ) __inline__ +# else +# define VULKAN_HPP_INLINE inline +# endif +# elif defined( __GNUC__ ) +# define VULKAN_HPP_INLINE __attribute__( ( always_inline ) ) __inline__ +# elif defined( _MSC_VER ) +# define VULKAN_HPP_INLINE inline +# else +# define VULKAN_HPP_INLINE inline +# endif +#endif + +#if ( VULKAN_HPP_TYPESAFE_CONVERSION == 1 ) +# define VULKAN_HPP_TYPESAFE_EXPLICIT +#else +# define VULKAN_HPP_TYPESAFE_EXPLICIT explicit +#endif + +#if defined( __cpp_constexpr ) +# define VULKAN_HPP_CONSTEXPR constexpr +# if 201304 <= __cpp_constexpr +# define VULKAN_HPP_CONSTEXPR_14 constexpr +# else +# define VULKAN_HPP_CONSTEXPR_14 +# endif +# if ( 201907 <= __cpp_constexpr ) && ( !defined( __GNUC__ ) || ( 110400 < GCC_VERSION ) ) +# define VULKAN_HPP_CONSTEXPR_20 constexpr +# else +# define VULKAN_HPP_CONSTEXPR_20 +# endif +# define VULKAN_HPP_CONST_OR_CONSTEXPR constexpr +#else +# define VULKAN_HPP_CONSTEXPR +# define VULKAN_HPP_CONSTEXPR_14 +# define VULKAN_HPP_CONST_OR_CONSTEXPR const +#endif + +#if !defined( VULKAN_HPP_CONSTEXPR_INLINE ) +# if 201606L <= __cpp_inline_variables +# define VULKAN_HPP_CONSTEXPR_INLINE VULKAN_HPP_CONSTEXPR inline +# else +# define VULKAN_HPP_CONSTEXPR_INLINE VULKAN_HPP_CONSTEXPR +# endif +#endif + +#if !defined( VULKAN_HPP_NOEXCEPT ) +# if defined( _MSC_VER ) && ( _MSC_VER <= 1800 ) +# define VULKAN_HPP_NOEXCEPT +# else +# define VULKAN_HPP_NOEXCEPT noexcept +# define VULKAN_HPP_HAS_NOEXCEPT 1 +# if defined( VULKAN_HPP_NO_EXCEPTIONS ) +# define VULKAN_HPP_NOEXCEPT_WHEN_NO_EXCEPTIONS noexcept +# else +# define VULKAN_HPP_NOEXCEPT_WHEN_NO_EXCEPTIONS +# endif +# endif +#endif + +#if 14 <= VULKAN_HPP_CPP_VERSION +# define VULKAN_HPP_DEPRECATED( msg ) [[deprecated( msg )]] +#else +# define VULKAN_HPP_DEPRECATED( msg ) +#endif + +#if ( 17 <= VULKAN_HPP_CPP_VERSION ) && !defined( VULKAN_HPP_NO_NODISCARD_WARNINGS ) +# define VULKAN_HPP_NODISCARD [[nodiscard]] +# if defined( VULKAN_HPP_NO_EXCEPTIONS ) +# define VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS [[nodiscard]] +# else +# define VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS +# endif +#else +# define VULKAN_HPP_NODISCARD +# define VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS +#endif + +#if !defined( VULKAN_HPP_NAMESPACE ) +# define VULKAN_HPP_NAMESPACE vk +#endif + +#define VULKAN_HPP_STRINGIFY2( text ) #text +#define VULKAN_HPP_STRINGIFY( text ) VULKAN_HPP_STRINGIFY2( text ) +#define VULKAN_HPP_NAMESPACE_STRING VULKAN_HPP_STRINGIFY( VULKAN_HPP_NAMESPACE ) + +#if !defined( VULKAN_HPP_DISPATCH_LOADER_DYNAMIC ) +# if defined( VK_NO_PROTOTYPES ) +# define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 +# else +# define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 0 +# endif +#endif + +#if !defined( VULKAN_HPP_STORAGE_API ) +# if defined( VULKAN_HPP_STORAGE_SHARED ) +# if defined( _MSC_VER ) +# if defined( VULKAN_HPP_STORAGE_SHARED_EXPORT ) +# define VULKAN_HPP_STORAGE_API __declspec( dllexport ) +# else +# define VULKAN_HPP_STORAGE_API __declspec( dllimport ) +# endif +# elif defined( __clang__ ) || defined( __GNUC__ ) +# if defined( VULKAN_HPP_STORAGE_SHARED_EXPORT ) +# define VULKAN_HPP_STORAGE_API __attribute__( ( visibility( "default" ) ) ) +# else +# define VULKAN_HPP_STORAGE_API +# endif +# else +# define VULKAN_HPP_STORAGE_API +# pragma warning Unknown import / export semantics +# endif +# else +# define VULKAN_HPP_STORAGE_API +# endif +#endif + +namespace VULKAN_HPP_NAMESPACE +{ + class DispatchLoaderDynamic; +} // namespace VULKAN_HPP_NAMESPACE + +#if !defined( VULKAN_HPP_DEFAULT_DISPATCHER ) +# if VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1 +# define VULKAN_HPP_DEFAULT_DISPATCHER ::VULKAN_HPP_NAMESPACE::defaultDispatchLoaderDynamic +# define VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE \ + namespace VULKAN_HPP_NAMESPACE \ + { \ + VULKAN_HPP_STORAGE_API ::VULKAN_HPP_NAMESPACE::DispatchLoaderDynamic defaultDispatchLoaderDynamic; \ + } + +namespace VULKAN_HPP_NAMESPACE +{ + extern VULKAN_HPP_STORAGE_API VULKAN_HPP_NAMESPACE::DispatchLoaderDynamic defaultDispatchLoaderDynamic; +} // namespace VULKAN_HPP_NAMESPACE +# else +# define VULKAN_HPP_DEFAULT_DISPATCHER ::VULKAN_HPP_NAMESPACE::getDispatchLoaderStatic() +# define VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE +# endif +#endif + +#if !defined( VULKAN_HPP_DEFAULT_DISPATCHER_TYPE ) +# if VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1 +# define VULKAN_HPP_DEFAULT_DISPATCHER_TYPE ::VULKAN_HPP_NAMESPACE::DispatchLoaderDynamic +# else +# define VULKAN_HPP_DEFAULT_DISPATCHER_TYPE ::VULKAN_HPP_NAMESPACE::DispatchLoaderStatic +# endif +#endif + +#if defined( VULKAN_HPP_NO_DEFAULT_DISPATCHER ) +# define VULKAN_HPP_DEFAULT_ARGUMENT_ASSIGNMENT +# define VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT +# define VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT +#else +# define VULKAN_HPP_DEFAULT_ARGUMENT_ASSIGNMENT = {} +# define VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT = nullptr +# define VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT = VULKAN_HPP_DEFAULT_DISPATCHER +#endif + +#if !defined( VULKAN_HPP_EXPECTED ) && ( 23 <= VULKAN_HPP_CPP_VERSION ) && defined( __cpp_lib_expected ) +# include +# define VULKAN_HPP_EXPECTED std::expected +# define VULKAN_HPP_UNEXPECTED std::unexpected +#endif + +#if !defined( VULKAN_HPP_RAII_NAMESPACE ) +# define VULKAN_HPP_RAII_NAMESPACE raii +#endif + +#if defined( VULKAN_HPP_NO_EXCEPTIONS ) && defined( VULKAN_HPP_EXPECTED ) +# define VULKAN_HPP_RAII_NO_EXCEPTIONS +# define VULKAN_HPP_RAII_CREATE_NOEXCEPT noexcept +#else +# define VULKAN_HPP_RAII_CREATE_NOEXCEPT +#endif + +#endif \ No newline at end of file diff --git a/external/vulkan/vulkan_ios.h b/external/vulkan/vulkan_ios.h index 5792205..22ed2c0 100644 --- a/external/vulkan/vulkan_ios.h +++ b/external/vulkan/vulkan_ios.h @@ -2,7 +2,7 @@ #define VULKAN_IOS_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ extern "C" { +// VK_MVK_ios_surface is a preprocessor guard. Do not pass it to API calls. #define VK_MVK_ios_surface 1 #define VK_MVK_IOS_SURFACE_SPEC_VERSION 3 #define VK_MVK_IOS_SURFACE_EXTENSION_NAME "VK_MVK_ios_surface" diff --git a/external/vulkan/vulkan_macos.h b/external/vulkan/vulkan_macos.h index 8e197c7..a7f5613 100644 --- a/external/vulkan/vulkan_macos.h +++ b/external/vulkan/vulkan_macos.h @@ -2,7 +2,7 @@ #define VULKAN_MACOS_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ extern "C" { +// VK_MVK_macos_surface is a preprocessor guard. Do not pass it to API calls. #define VK_MVK_macos_surface 1 #define VK_MVK_MACOS_SURFACE_SPEC_VERSION 3 #define VK_MVK_MACOS_SURFACE_EXTENSION_NAME "VK_MVK_macos_surface" diff --git a/external/vulkan/vulkan_metal.h b/external/vulkan/vulkan_metal.h index 11b9640..e6f7bf7 100644 --- a/external/vulkan/vulkan_metal.h +++ b/external/vulkan/vulkan_metal.h @@ -2,7 +2,7 @@ #define VULKAN_METAL_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ extern "C" { +// VK_EXT_metal_surface is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_metal_surface 1 #ifdef __OBJC__ @class CAMetalLayer; @@ -47,6 +48,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT( #endif +// VK_EXT_metal_objects is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_metal_objects 1 #ifdef __OBJC__ @protocol MTLDevice; diff --git a/external/vulkan/vulkan_raii.hpp b/external/vulkan/vulkan_raii.hpp new file mode 100644 index 0000000..0149b00 Binary files /dev/null and b/external/vulkan/vulkan_raii.hpp differ diff --git a/external/vulkan/vulkan_screen.h b/external/vulkan/vulkan_screen.h index f0ef40a..7e84d4d 100644 --- a/external/vulkan/vulkan_screen.h +++ b/external/vulkan/vulkan_screen.h @@ -2,7 +2,7 @@ #define VULKAN_SCREEN_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ extern "C" { +// VK_QNX_screen_surface is a preprocessor guard. Do not pass it to API calls. #define VK_QNX_screen_surface 1 #define VK_QNX_SCREEN_SURFACE_SPEC_VERSION 1 #define VK_QNX_SCREEN_SURFACE_EXTENSION_NAME "VK_QNX_screen_surface" @@ -47,6 +48,59 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceScreenPresentationSupportQNX( struct _screen_window* window); #endif + +// VK_QNX_external_memory_screen_buffer is a preprocessor guard. Do not pass it to API calls. +#define VK_QNX_external_memory_screen_buffer 1 +#define VK_QNX_EXTERNAL_MEMORY_SCREEN_BUFFER_SPEC_VERSION 1 +#define VK_QNX_EXTERNAL_MEMORY_SCREEN_BUFFER_EXTENSION_NAME "VK_QNX_external_memory_screen_buffer" +typedef struct VkScreenBufferPropertiesQNX { + VkStructureType sType; + void* pNext; + VkDeviceSize allocationSize; + uint32_t memoryTypeBits; +} VkScreenBufferPropertiesQNX; + +typedef struct VkScreenBufferFormatPropertiesQNX { + VkStructureType sType; + void* pNext; + VkFormat format; + uint64_t externalFormat; + uint64_t screenUsage; + VkFormatFeatureFlags formatFeatures; + VkComponentMapping samplerYcbcrConversionComponents; + VkSamplerYcbcrModelConversion suggestedYcbcrModel; + VkSamplerYcbcrRange suggestedYcbcrRange; + VkChromaLocation suggestedXChromaOffset; + VkChromaLocation suggestedYChromaOffset; +} VkScreenBufferFormatPropertiesQNX; + +typedef struct VkImportScreenBufferInfoQNX { + VkStructureType sType; + const void* pNext; + struct _screen_buffer* buffer; +} VkImportScreenBufferInfoQNX; + +typedef struct VkExternalFormatQNX { + VkStructureType sType; + void* pNext; + uint64_t externalFormat; +} VkExternalFormatQNX; + +typedef struct VkPhysicalDeviceExternalMemoryScreenBufferFeaturesQNX { + VkStructureType sType; + void* pNext; + VkBool32 screenBufferImport; +} VkPhysicalDeviceExternalMemoryScreenBufferFeaturesQNX; + +typedef VkResult (VKAPI_PTR *PFN_vkGetScreenBufferPropertiesQNX)(VkDevice device, const struct _screen_buffer* buffer, VkScreenBufferPropertiesQNX* pProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetScreenBufferPropertiesQNX( + VkDevice device, + const struct _screen_buffer* buffer, + VkScreenBufferPropertiesQNX* pProperties); +#endif + #ifdef __cplusplus } #endif diff --git a/external/vulkan/vulkan_shared.hpp b/external/vulkan/vulkan_shared.hpp new file mode 100644 index 0000000..8b2697a --- /dev/null +++ b/external/vulkan/vulkan_shared.hpp @@ -0,0 +1,1087 @@ +// Copyright 2015-2024 The Khronos Group Inc. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT +// + +// This header is generated from the Khronos Vulkan XML API Registry. + +#ifndef VULKAN_SHARED_HPP +#define VULKAN_SHARED_HPP + +#include // std::atomic_size_t +#include + +namespace VULKAN_HPP_NAMESPACE +{ +#if !defined( VULKAN_HPP_NO_SMART_HANDLE ) + + template + class SharedHandleTraits; + + class NoDestructor + { + }; + + template + struct HasDestructorType : std::false_type + { + }; + + template + struct HasDestructorType::DestructorType() )> : std::true_type + { + }; + + template + struct GetDestructorType + { + using type = NoDestructor; + }; + + template + struct GetDestructorType::value>::type> + { + using type = typename SharedHandleTraits::DestructorType; + }; + + template + using DestructorTypeOf = typename GetDestructorType::type; + + template + struct HasDestructor : std::integral_constant, NoDestructor>::value> + { + }; + + //===================================================================================================================== + + template + class SharedHandle; + + template + struct SharedHeader + { + SharedHeader( SharedHandle parent, Deleter deleter = Deleter() ) VULKAN_HPP_NOEXCEPT + : parent( std::move( parent ) ) + , deleter( std::move( deleter ) ) + { + } + + SharedHandle parent; + Deleter deleter; + }; + + template + struct SharedHeader + { + SharedHeader( Deleter deleter = Deleter() ) VULKAN_HPP_NOEXCEPT : deleter( std::move( deleter ) ) {} + + Deleter deleter; + }; + + //===================================================================================================================== + + template + class ReferenceCounter + { + public: + template + ReferenceCounter( Args &&... control_args ) : m_header( std::forward( control_args )... ) + { + } + + ReferenceCounter( const ReferenceCounter & ) = delete; + ReferenceCounter & operator=( const ReferenceCounter & ) = delete; + + public: + size_t addRef() VULKAN_HPP_NOEXCEPT + { + // Relaxed memory order is sufficient since this does not impose any ordering on other operations + return m_ref_cnt.fetch_add( 1, std::memory_order_relaxed ); + } + + size_t release() VULKAN_HPP_NOEXCEPT + { + // A release memory order to ensure that all releases are ordered + return m_ref_cnt.fetch_sub( 1, std::memory_order_release ); + } + + public: + std::atomic_size_t m_ref_cnt{ 1 }; + HeaderType m_header{}; + }; + + //===================================================================================================================== + + template > + class SharedHandleBase + { + public: + SharedHandleBase() = default; + + template + SharedHandleBase( HandleType handle, Args &&... control_args ) + : m_control( new ReferenceCounter( std::forward( control_args )... ) ), m_handle( handle ) + { + } + + SharedHandleBase( const SharedHandleBase & o ) VULKAN_HPP_NOEXCEPT + { + o.addRef(); + m_handle = o.m_handle; + m_control = o.m_control; + } + + SharedHandleBase( SharedHandleBase && o ) VULKAN_HPP_NOEXCEPT + : m_control( o.m_control ) + , m_handle( o.m_handle ) + { + o.m_handle = nullptr; + o.m_control = nullptr; + } + + SharedHandleBase & operator=( const SharedHandleBase & o ) VULKAN_HPP_NOEXCEPT + { + SharedHandleBase( o ).swap( *this ); + return *this; + } + + SharedHandleBase & operator=( SharedHandleBase && o ) VULKAN_HPP_NOEXCEPT + { + SharedHandleBase( std::move( o ) ).swap( *this ); + return *this; + } + + ~SharedHandleBase() + { + // only this function owns the last reference to the control block + // the same principle is used in the default deleter of std::shared_ptr + if ( m_control && ( m_control->release() == 1 ) ) + { + // noop in x86, but does thread synchronization in ARM + // it is required to ensure that last thread is getting to destroy the control block + // by ordering all atomic operations before this fence + std::atomic_thread_fence( std::memory_order_acquire ); + ForwardType::internalDestroy( getHeader(), m_handle ); + delete m_control; + } + } + + public: + HandleType get() const VULKAN_HPP_NOEXCEPT + { + return m_handle; + } + + HandleType operator*() const VULKAN_HPP_NOEXCEPT + { + return m_handle; + } + + explicit operator bool() const VULKAN_HPP_NOEXCEPT + { + return bool( m_handle ); + } + +# if defined( VULKAN_HPP_SMART_HANDLE_IMPLICIT_CAST ) + operator HandleType() const VULKAN_HPP_NOEXCEPT + { + return m_handle; + } +# endif + + const HandleType * operator->() const VULKAN_HPP_NOEXCEPT + { + return &m_handle; + } + + HandleType * operator->() VULKAN_HPP_NOEXCEPT + { + return &m_handle; + } + + void reset() VULKAN_HPP_NOEXCEPT + { + SharedHandleBase().swap( *this ); + } + + void swap( SharedHandleBase & o ) VULKAN_HPP_NOEXCEPT + { + std::swap( m_handle, o.m_handle ); + std::swap( m_control, o.m_control ); + } + + template + typename std::enable_if::value, const SharedHandle> &>::type getDestructorType() const VULKAN_HPP_NOEXCEPT + { + return getHeader().parent; + } + + protected: + template + static typename std::enable_if::value, void>::type internalDestroy( const HeaderType & control, HandleType handle ) VULKAN_HPP_NOEXCEPT + { + control.deleter.destroy( handle ); + } + + template + static typename std::enable_if::value, void>::type internalDestroy( const HeaderType & control, HandleType handle ) VULKAN_HPP_NOEXCEPT + { + control.deleter.destroy( control.parent.get(), handle ); + } + + const HeaderType & getHeader() const VULKAN_HPP_NOEXCEPT + { + return m_control->m_header; + } + + private: + void addRef() const VULKAN_HPP_NOEXCEPT + { + if ( m_control ) + m_control->addRef(); + } + + protected: + ReferenceCounter * m_control = nullptr; + HandleType m_handle{}; + }; + + template + class SharedHandle : public SharedHandleBase, typename SharedHandleTraits::deleter>> + { + private: + using BaseType = SharedHandleBase, typename SharedHandleTraits::deleter>>; + using DeleterType = typename SharedHandleTraits::deleter; + friend BaseType; + + public: + SharedHandle() = default; + + template ::value>::type> + explicit SharedHandle( HandleType handle, SharedHandle> parent, DeleterType deleter = DeleterType() ) VULKAN_HPP_NOEXCEPT + : BaseType( handle, std::move( parent ), std::move( deleter ) ) + { + } + + template ::value>::type> + explicit SharedHandle( HandleType handle, DeleterType deleter = DeleterType() ) VULKAN_HPP_NOEXCEPT : BaseType( handle, std::move( deleter ) ) + { + } + + protected: + using BaseType::internalDestroy; + }; + + template + class SharedHandleTraits; + +// Silence the function cast warnings. +# if defined( __GNUC__ ) && !defined( __clang__ ) && !defined( __INTEL_COMPILER ) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcast-function-type" +# endif + + template + class ObjectDestroyShared + { + public: + using DestructorType = typename SharedHandleTraits::DestructorType; + + template + using DestroyFunctionPointerType = + typename std::conditional::value, + void ( DestructorType::* )( HandleType, const AllocationCallbacks *, const Dispatcher & ) const, + void ( HandleType::* )( const AllocationCallbacks *, const Dispatcher & ) const>::type; + + using SelectorType = typename std::conditional::value, DestructorType, HandleType>::type; + + template + ObjectDestroyShared( Optional allocationCallbacks VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT, + const Dispatcher & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) + : m_destroy( reinterpret_cast( static_cast>( &SelectorType::destroy ) ) ) + , m_dispatch( &dispatch ) + , m_allocationCallbacks( allocationCallbacks ) + { + } + + public: + template + typename std::enable_if::value, void>::type destroy( DestructorType parent, HandleType handle ) const VULKAN_HPP_NOEXCEPT + { + VULKAN_HPP_ASSERT( m_destroy && m_dispatch ); + ( parent.*m_destroy )( handle, m_allocationCallbacks, *m_dispatch ); + } + + template + typename std::enable_if::value, void>::type destroy( HandleType handle ) const VULKAN_HPP_NOEXCEPT + { + VULKAN_HPP_ASSERT( m_destroy && m_dispatch ); + ( handle.*m_destroy )( m_allocationCallbacks, *m_dispatch ); + } + + private: + DestroyFunctionPointerType m_destroy = nullptr; + const DispatchLoaderBase * m_dispatch = nullptr; + Optional m_allocationCallbacks = nullptr; + }; + + template + class ObjectFreeShared + { + public: + using DestructorType = typename SharedHandleTraits::DestructorType; + + template + using DestroyFunctionPointerType = void ( DestructorType::* )( HandleType, const AllocationCallbacks *, const Dispatcher & ) const; + + template + ObjectFreeShared( Optional allocationCallbacks VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT, + const Dispatcher & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) + : m_destroy( reinterpret_cast( static_cast>( &DestructorType::free ) ) ) + , m_dispatch( &dispatch ) + , m_allocationCallbacks( allocationCallbacks ) + { + } + + public: + void destroy( DestructorType parent, HandleType handle ) const VULKAN_HPP_NOEXCEPT + { + VULKAN_HPP_ASSERT( m_destroy && m_dispatch ); + ( parent.*m_destroy )( handle, m_allocationCallbacks, *m_dispatch ); + } + + private: + DestroyFunctionPointerType m_destroy = nullptr; + const DispatchLoaderBase * m_dispatch = nullptr; + Optional m_allocationCallbacks = nullptr; + }; + + template + class ObjectReleaseShared + { + public: + using DestructorType = typename SharedHandleTraits::DestructorType; + + template + using DestroyFunctionPointerType = void ( DestructorType::* )( HandleType, const Dispatcher & ) const; + + template + ObjectReleaseShared( const Dispatcher & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) + : m_destroy( reinterpret_cast( static_cast>( &DestructorType::release ) ) ) + , m_dispatch( &dispatch ) + { + } + + public: + void destroy( DestructorType parent, HandleType handle ) const VULKAN_HPP_NOEXCEPT + { + VULKAN_HPP_ASSERT( m_destroy && m_dispatch ); + ( parent.*m_destroy )( handle, *m_dispatch ); + } + + private: + DestroyFunctionPointerType m_destroy = nullptr; + const DispatchLoaderBase * m_dispatch = nullptr; + }; + + template + class PoolFreeShared + { + public: + using DestructorType = typename SharedHandleTraits::DestructorType; + + template + using ReturnType = decltype( std::declval().free( PoolType(), 0u, nullptr, Dispatcher() ) ); + + template + using DestroyFunctionPointerType = ReturnType ( DestructorType::* )( PoolType, uint32_t, const HandleType *, const Dispatcher & ) const; + + PoolFreeShared() = default; + + template + PoolFreeShared( SharedHandle pool, const Dispatcher & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) + : m_destroy( reinterpret_cast( static_cast>( &DestructorType::free ) ) ) + , m_dispatch( &dispatch ) + , m_pool( std::move( pool ) ) + { + } + + public: + void destroy( DestructorType parent, HandleType handle ) const VULKAN_HPP_NOEXCEPT + { + VULKAN_HPP_ASSERT( m_destroy && m_dispatch ); + ( parent.*m_destroy )( m_pool.get(), 1u, &handle, *m_dispatch ); + } + + private: + DestroyFunctionPointerType m_destroy = nullptr; + const DispatchLoaderBase * m_dispatch = nullptr; + SharedHandle m_pool{}; + }; + +# if defined( __GNUC__ ) && !defined( __clang__ ) && !defined( __INTEL_COMPILER ) +# pragma GCC diagnostic pop +# endif + + //====================== + //=== SHARED HANDLEs === + //====================== + + //=== VK_VERSION_1_0 === + template <> + class SharedHandleTraits + { + public: + using DestructorType = NoDestructor; + using deleter = ObjectDestroyShared; + }; + + using SharedInstance = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = NoDestructor; + using deleter = ObjectDestroyShared; + }; + + using SharedDevice = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectFreeShared; + }; + + using SharedDeviceMemory = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedFence = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedSemaphore = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedEvent = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedQueryPool = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedBuffer = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedBufferView = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedImage = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedImageView = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedShaderModule = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedPipelineCache = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedPipeline = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedPipelineLayout = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedSampler = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedDescriptorPool = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = PoolFreeShared; + }; + + using SharedDescriptorSet = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedDescriptorSetLayout = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedFramebuffer = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedRenderPass = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedCommandPool = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = PoolFreeShared; + }; + + using SharedCommandBuffer = SharedHandle; + + //=== VK_VERSION_1_1 === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedSamplerYcbcrConversion = SharedHandle; + using SharedSamplerYcbcrConversionKHR = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedDescriptorUpdateTemplate = SharedHandle; + using SharedDescriptorUpdateTemplateKHR = SharedHandle; + + //=== VK_VERSION_1_3 === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedPrivateDataSlot = SharedHandle; + using SharedPrivateDataSlotEXT = SharedHandle; + + //=== VK_KHR_surface === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Instance; + using deleter = ObjectDestroyShared; + }; + + using SharedSurfaceKHR = SharedHandle; + + //=== VK_KHR_swapchain === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedSwapchainKHR = SharedHandle; + + //=== VK_KHR_display === + template <> + class SharedHandleTraits + { + public: + using DestructorType = PhysicalDevice; + using deleter = ObjectDestroyShared; + }; + + using SharedDisplayKHR = SharedHandle; + + //=== VK_EXT_debug_report === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Instance; + using deleter = ObjectDestroyShared; + }; + + using SharedDebugReportCallbackEXT = SharedHandle; + + //=== VK_KHR_video_queue === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedVideoSessionKHR = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedVideoSessionParametersKHR = SharedHandle; + + //=== VK_NVX_binary_import === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedCuModuleNVX = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedCuFunctionNVX = SharedHandle; + + //=== VK_EXT_debug_utils === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Instance; + using deleter = ObjectDestroyShared; + }; + + using SharedDebugUtilsMessengerEXT = SharedHandle; + + //=== VK_KHR_acceleration_structure === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedAccelerationStructureKHR = SharedHandle; + + //=== VK_EXT_validation_cache === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedValidationCacheEXT = SharedHandle; + + //=== VK_NV_ray_tracing === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedAccelerationStructureNV = SharedHandle; + + //=== VK_INTEL_performance_query === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedPerformanceConfigurationINTEL = SharedHandle; + + //=== VK_KHR_deferred_host_operations === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedDeferredOperationKHR = SharedHandle; + + //=== VK_NV_device_generated_commands === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedIndirectCommandsLayoutNV = SharedHandle; + +# if defined( VK_ENABLE_BETA_EXTENSIONS ) + //=== VK_NV_cuda_kernel_launch === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedCudaModuleNV = SharedHandle; + + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedCudaFunctionNV = SharedHandle; +# endif /*VK_ENABLE_BETA_EXTENSIONS*/ + +# if defined( VK_USE_PLATFORM_FUCHSIA ) + //=== VK_FUCHSIA_buffer_collection === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedBufferCollectionFUCHSIA = SharedHandle; +# endif /*VK_USE_PLATFORM_FUCHSIA*/ + + //=== VK_EXT_opacity_micromap === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedMicromapEXT = SharedHandle; + + //=== VK_NV_optical_flow === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedOpticalFlowSessionNV = SharedHandle; + + //=== VK_EXT_shader_object === + template <> + class SharedHandleTraits + { + public: + using DestructorType = Device; + using deleter = ObjectDestroyShared; + }; + + using SharedShaderEXT = SharedHandle; + + enum class SwapchainOwns + { + no, + yes, + }; + + struct ImageHeader : SharedHeader, typename SharedHandleTraits::deleter> + { + ImageHeader( + SharedHandle> parent, + typename SharedHandleTraits::deleter deleter = typename SharedHandleTraits::deleter(), + SwapchainOwns swapchainOwned = SwapchainOwns::no ) VULKAN_HPP_NOEXCEPT + : SharedHeader, typename SharedHandleTraits::deleter>( std::move( parent ), + std::move( deleter ) ) + , swapchainOwned( swapchainOwned ) + { + } + + SwapchainOwns swapchainOwned = SwapchainOwns::no; + }; + + template <> + class SharedHandle : public SharedHandleBase + { + using BaseType = SharedHandleBase; + using DeleterType = typename SharedHandleTraits::deleter; + friend BaseType; + + public: + SharedHandle() = default; + + explicit SharedHandle( VULKAN_HPP_NAMESPACE::Image handle, + SharedHandle> parent, + SwapchainOwns swapchain_owned = SwapchainOwns::no, + DeleterType deleter = DeleterType() ) VULKAN_HPP_NOEXCEPT + : BaseType( handle, std::move( parent ), std::move( deleter ), swapchain_owned ) + { + } + + protected: + static void internalDestroy( const ImageHeader & control, VULKAN_HPP_NAMESPACE::Image handle ) VULKAN_HPP_NOEXCEPT + { + if ( control.swapchainOwned == SwapchainOwns::no ) + { + control.deleter.destroy( control.parent.get(), handle ); + } + } + }; + + struct SwapchainHeader + { + SwapchainHeader( SharedHandle surface, + SharedHandle> parent, + typename SharedHandleTraits::deleter deleter = + typename SharedHandleTraits::deleter() ) VULKAN_HPP_NOEXCEPT + : surface( std::move( surface ) ) + , parent( std::move( parent ) ) + , deleter( std::move( deleter ) ) + { + } + + SharedHandle surface{}; + SharedHandle> parent{}; + typename SharedHandleTraits::deleter deleter{}; + }; + + template <> + class SharedHandle : public SharedHandleBase + { + using BaseType = SharedHandleBase; + using DeleterType = typename SharedHandleTraits::deleter; + friend BaseType; + + public: + SharedHandle() = default; + + explicit SharedHandle( VULKAN_HPP_NAMESPACE::SwapchainKHR handle, + SharedHandle> parent, + SharedHandle surface, + DeleterType deleter = DeleterType() ) VULKAN_HPP_NOEXCEPT + : BaseType( handle, std::move( surface ), std::move( parent ), std::move( deleter ) ) + { + } + + public: + const SharedHandle & getSurface() const VULKAN_HPP_NOEXCEPT + { + return getHeader().surface; + } + + protected: + using BaseType::internalDestroy; + }; + + template + class SharedHandleBaseNoDestroy : public SharedHandleBase + { + public: + using SharedHandleBase::SharedHandleBase; + + const DestructorType & getDestructorType() const VULKAN_HPP_NOEXCEPT + { + return SharedHandleBase::getHeader(); + } + + protected: + static void internalDestroy( const DestructorType &, HandleType ) VULKAN_HPP_NOEXCEPT {} + }; + + //=== VK_VERSION_1_0 === + + template <> + class SharedHandle : public SharedHandleBaseNoDestroy + { + friend SharedHandleBase; + + public: + SharedHandle() = default; + + explicit SharedHandle( PhysicalDevice handle, SharedInstance parent ) noexcept + : SharedHandleBaseNoDestroy( handle, std::move( parent ) ) + { + } + }; + + using SharedPhysicalDevice = SharedHandle; + + template <> + class SharedHandle : public SharedHandleBaseNoDestroy + { + friend SharedHandleBase; + + public: + SharedHandle() = default; + + explicit SharedHandle( Queue handle, SharedDevice parent ) noexcept : SharedHandleBaseNoDestroy( handle, std::move( parent ) ) {} + }; + + using SharedQueue = SharedHandle; + + //=== VK_KHR_display === + + template <> + class SharedHandle : public SharedHandleBaseNoDestroy + { + friend SharedHandleBase; + + public: + SharedHandle() = default; + + explicit SharedHandle( DisplayModeKHR handle, SharedDisplayKHR parent ) noexcept + : SharedHandleBaseNoDestroy( handle, std::move( parent ) ) + { + } + }; + + using SharedDisplayModeKHR = SharedHandle; +#endif // !VULKAN_HPP_NO_SMART_HANDLE +} // namespace VULKAN_HPP_NAMESPACE +#endif // VULKAN_SHARED_HPP diff --git a/external/vulkan/vulkan_static_assertions.hpp b/external/vulkan/vulkan_static_assertions.hpp new file mode 100644 index 0000000..693977c Binary files /dev/null and b/external/vulkan/vulkan_static_assertions.hpp differ diff --git a/external/vulkan/vulkan_structs.hpp b/external/vulkan/vulkan_structs.hpp new file mode 100644 index 0000000..45d9c2b Binary files /dev/null and b/external/vulkan/vulkan_structs.hpp differ diff --git a/external/vulkan/vulkan_to_string.hpp b/external/vulkan/vulkan_to_string.hpp new file mode 100644 index 0000000..f32d156 Binary files /dev/null and b/external/vulkan/vulkan_to_string.hpp differ diff --git a/external/vulkan/vulkan_vi.h b/external/vulkan/vulkan_vi.h index 0355e7a..c145f4a 100644 --- a/external/vulkan/vulkan_vi.h +++ b/external/vulkan/vulkan_vi.h @@ -2,7 +2,7 @@ #define VULKAN_VI_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ extern "C" { +// VK_NN_vi_surface is a preprocessor guard. Do not pass it to API calls. #define VK_NN_vi_surface 1 #define VK_NN_VI_SURFACE_SPEC_VERSION 1 #define VK_NN_VI_SURFACE_EXTENSION_NAME "VK_NN_vi_surface" diff --git a/external/vulkan/vulkan_video.hpp b/external/vulkan/vulkan_video.hpp new file mode 100644 index 0000000..fb82aa3 --- /dev/null +++ b/external/vulkan/vulkan_video.hpp @@ -0,0 +1,3716 @@ +// Copyright 2021-2024 The Khronos Group Inc. +// SPDX-License-Identifier: Apache-2.0 OR MIT +// + +// This header is generated from the Khronos Vulkan XML API Registry. + +#ifndef VULKAN_VIDEO_HPP +#define VULKAN_VIDEO_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined( VULKAN_HPP_VIDEO_NAMESPACE ) +# define VULKAN_HPP_VIDEO_NAMESPACE video +#endif + +namespace VULKAN_HPP_NAMESPACE +{ + namespace VULKAN_HPP_VIDEO_NAMESPACE + { + + //============= + //=== ENUMs === + //============= + + //=== vulkan_video_codec_h264std === + + enum class H264ChromaFormatIdc + { + eMonochrome = STD_VIDEO_H264_CHROMA_FORMAT_IDC_MONOCHROME, + e420 = STD_VIDEO_H264_CHROMA_FORMAT_IDC_420, + e422 = STD_VIDEO_H264_CHROMA_FORMAT_IDC_422, + e444 = STD_VIDEO_H264_CHROMA_FORMAT_IDC_444, + eInvalid = STD_VIDEO_H264_CHROMA_FORMAT_IDC_INVALID + }; + + enum class H264ProfileIdc + { + eBaseline = STD_VIDEO_H264_PROFILE_IDC_BASELINE, + eMain = STD_VIDEO_H264_PROFILE_IDC_MAIN, + eHigh = STD_VIDEO_H264_PROFILE_IDC_HIGH, + eHigh444Predictive = STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE, + eInvalid = STD_VIDEO_H264_PROFILE_IDC_INVALID + }; + + enum class H264LevelIdc + { + e1_0 = STD_VIDEO_H264_LEVEL_IDC_1_0, + e1_1 = STD_VIDEO_H264_LEVEL_IDC_1_1, + e1_2 = STD_VIDEO_H264_LEVEL_IDC_1_2, + e1_3 = STD_VIDEO_H264_LEVEL_IDC_1_3, + e2_0 = STD_VIDEO_H264_LEVEL_IDC_2_0, + e2_1 = STD_VIDEO_H264_LEVEL_IDC_2_1, + e2_2 = STD_VIDEO_H264_LEVEL_IDC_2_2, + e3_0 = STD_VIDEO_H264_LEVEL_IDC_3_0, + e3_1 = STD_VIDEO_H264_LEVEL_IDC_3_1, + e3_2 = STD_VIDEO_H264_LEVEL_IDC_3_2, + e4_0 = STD_VIDEO_H264_LEVEL_IDC_4_0, + e4_1 = STD_VIDEO_H264_LEVEL_IDC_4_1, + e4_2 = STD_VIDEO_H264_LEVEL_IDC_4_2, + e5_0 = STD_VIDEO_H264_LEVEL_IDC_5_0, + e5_1 = STD_VIDEO_H264_LEVEL_IDC_5_1, + e5_2 = STD_VIDEO_H264_LEVEL_IDC_5_2, + e6_0 = STD_VIDEO_H264_LEVEL_IDC_6_0, + e6_1 = STD_VIDEO_H264_LEVEL_IDC_6_1, + e6_2 = STD_VIDEO_H264_LEVEL_IDC_6_2, + eInvalid = STD_VIDEO_H264_LEVEL_IDC_INVALID + }; + + enum class H264PocType + { + e0 = STD_VIDEO_H264_POC_TYPE_0, + e1 = STD_VIDEO_H264_POC_TYPE_1, + e2 = STD_VIDEO_H264_POC_TYPE_2, + eInvalid = STD_VIDEO_H264_POC_TYPE_INVALID + }; + + enum class H264AspectRatioIdc + { + eUnspecified = STD_VIDEO_H264_ASPECT_RATIO_IDC_UNSPECIFIED, + eSquare = STD_VIDEO_H264_ASPECT_RATIO_IDC_SQUARE, + e12_11 = STD_VIDEO_H264_ASPECT_RATIO_IDC_12_11, + e10_11 = STD_VIDEO_H264_ASPECT_RATIO_IDC_10_11, + e16_11 = STD_VIDEO_H264_ASPECT_RATIO_IDC_16_11, + e40_33 = STD_VIDEO_H264_ASPECT_RATIO_IDC_40_33, + e24_11 = STD_VIDEO_H264_ASPECT_RATIO_IDC_24_11, + e20_11 = STD_VIDEO_H264_ASPECT_RATIO_IDC_20_11, + e32_11 = STD_VIDEO_H264_ASPECT_RATIO_IDC_32_11, + e80_33 = STD_VIDEO_H264_ASPECT_RATIO_IDC_80_33, + e18_11 = STD_VIDEO_H264_ASPECT_RATIO_IDC_18_11, + e15_11 = STD_VIDEO_H264_ASPECT_RATIO_IDC_15_11, + e64_33 = STD_VIDEO_H264_ASPECT_RATIO_IDC_64_33, + e160_99 = STD_VIDEO_H264_ASPECT_RATIO_IDC_160_99, + e4_3 = STD_VIDEO_H264_ASPECT_RATIO_IDC_4_3, + e3_2 = STD_VIDEO_H264_ASPECT_RATIO_IDC_3_2, + e2_1 = STD_VIDEO_H264_ASPECT_RATIO_IDC_2_1, + eExtendedSar = STD_VIDEO_H264_ASPECT_RATIO_IDC_EXTENDED_SAR, + eInvalid = STD_VIDEO_H264_ASPECT_RATIO_IDC_INVALID + }; + + enum class H264WeightedBipredIdc + { + eDefault = STD_VIDEO_H264_WEIGHTED_BIPRED_IDC_DEFAULT, + eExplicit = STD_VIDEO_H264_WEIGHTED_BIPRED_IDC_EXPLICIT, + eImplicit = STD_VIDEO_H264_WEIGHTED_BIPRED_IDC_IMPLICIT, + eInvalid = STD_VIDEO_H264_WEIGHTED_BIPRED_IDC_INVALID + }; + + enum class H264ModificationOfPicNumsIdc + { + eShortTermSubtract = STD_VIDEO_H264_MODIFICATION_OF_PIC_NUMS_IDC_SHORT_TERM_SUBTRACT, + eShortTermAdd = STD_VIDEO_H264_MODIFICATION_OF_PIC_NUMS_IDC_SHORT_TERM_ADD, + eLongTerm = STD_VIDEO_H264_MODIFICATION_OF_PIC_NUMS_IDC_LONG_TERM, + eEnd = STD_VIDEO_H264_MODIFICATION_OF_PIC_NUMS_IDC_END, + eInvalid = STD_VIDEO_H264_MODIFICATION_OF_PIC_NUMS_IDC_INVALID + }; + + enum class H264MemMgmtControlOp + { + eEnd = STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_END, + eUnmarkShortTerm = STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_UNMARK_SHORT_TERM, + eUnmarkLongTerm = STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_UNMARK_LONG_TERM, + eMarkLongTerm = STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_MARK_LONG_TERM, + eSetMaxLongTermIndex = STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_SET_MAX_LONG_TERM_INDEX, + eUnmarkAll = STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_UNMARK_ALL, + eMarkCurrentAsLongTerm = STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_MARK_CURRENT_AS_LONG_TERM, + eInvalid = STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_INVALID + }; + + enum class H264CabacInitIdc + { + e0 = STD_VIDEO_H264_CABAC_INIT_IDC_0, + e1 = STD_VIDEO_H264_CABAC_INIT_IDC_1, + e2 = STD_VIDEO_H264_CABAC_INIT_IDC_2, + eInvalid = STD_VIDEO_H264_CABAC_INIT_IDC_INVALID + }; + + enum class H264DisableDeblockingFilterIdc + { + eDisabled = STD_VIDEO_H264_DISABLE_DEBLOCKING_FILTER_IDC_DISABLED, + eEnabled = STD_VIDEO_H264_DISABLE_DEBLOCKING_FILTER_IDC_ENABLED, + ePartial = STD_VIDEO_H264_DISABLE_DEBLOCKING_FILTER_IDC_PARTIAL, + eInvalid = STD_VIDEO_H264_DISABLE_DEBLOCKING_FILTER_IDC_INVALID + }; + + enum class H264SliceType + { + eP = STD_VIDEO_H264_SLICE_TYPE_P, + eB = STD_VIDEO_H264_SLICE_TYPE_B, + eI = STD_VIDEO_H264_SLICE_TYPE_I, + eInvalid = STD_VIDEO_H264_SLICE_TYPE_INVALID + }; + + enum class H264PictureType + { + eP = STD_VIDEO_H264_PICTURE_TYPE_P, + eB = STD_VIDEO_H264_PICTURE_TYPE_B, + eI = STD_VIDEO_H264_PICTURE_TYPE_I, + eIdr = STD_VIDEO_H264_PICTURE_TYPE_IDR, + eInvalid = STD_VIDEO_H264_PICTURE_TYPE_INVALID + }; + + enum class H264NonVclNaluType + { + eSps = STD_VIDEO_H264_NON_VCL_NALU_TYPE_SPS, + ePps = STD_VIDEO_H264_NON_VCL_NALU_TYPE_PPS, + eAud = STD_VIDEO_H264_NON_VCL_NALU_TYPE_AUD, + ePrefix = STD_VIDEO_H264_NON_VCL_NALU_TYPE_PREFIX, + eEndOfSequence = STD_VIDEO_H264_NON_VCL_NALU_TYPE_END_OF_SEQUENCE, + eEndOfStream = STD_VIDEO_H264_NON_VCL_NALU_TYPE_END_OF_STREAM, + ePrecoded = STD_VIDEO_H264_NON_VCL_NALU_TYPE_PRECODED, + eInvalid = STD_VIDEO_H264_NON_VCL_NALU_TYPE_INVALID + }; + + //=== vulkan_video_codec_h264std_decode === + + enum class DecodeH264FieldOrderCount + { + eTop = STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_TOP, + eBottom = STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_BOTTOM, + eInvalid = STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_INVALID + }; + + //=== vulkan_video_codec_h265std === + + enum class H265ChromaFormatIdc + { + eMonochrome = STD_VIDEO_H265_CHROMA_FORMAT_IDC_MONOCHROME, + e420 = STD_VIDEO_H265_CHROMA_FORMAT_IDC_420, + e422 = STD_VIDEO_H265_CHROMA_FORMAT_IDC_422, + e444 = STD_VIDEO_H265_CHROMA_FORMAT_IDC_444, + eInvalid = STD_VIDEO_H265_CHROMA_FORMAT_IDC_INVALID + }; + + enum class H265ProfileIdc + { + eMain = STD_VIDEO_H265_PROFILE_IDC_MAIN, + eMain10 = STD_VIDEO_H265_PROFILE_IDC_MAIN_10, + eMainStillPicture = STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE, + eFormatRangeExtensions = STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS, + eSccExtensions = STD_VIDEO_H265_PROFILE_IDC_SCC_EXTENSIONS, + eInvalid = STD_VIDEO_H265_PROFILE_IDC_INVALID + }; + + enum class H265LevelIdc + { + e1_0 = STD_VIDEO_H265_LEVEL_IDC_1_0, + e2_0 = STD_VIDEO_H265_LEVEL_IDC_2_0, + e2_1 = STD_VIDEO_H265_LEVEL_IDC_2_1, + e3_0 = STD_VIDEO_H265_LEVEL_IDC_3_0, + e3_1 = STD_VIDEO_H265_LEVEL_IDC_3_1, + e4_0 = STD_VIDEO_H265_LEVEL_IDC_4_0, + e4_1 = STD_VIDEO_H265_LEVEL_IDC_4_1, + e5_0 = STD_VIDEO_H265_LEVEL_IDC_5_0, + e5_1 = STD_VIDEO_H265_LEVEL_IDC_5_1, + e5_2 = STD_VIDEO_H265_LEVEL_IDC_5_2, + e6_0 = STD_VIDEO_H265_LEVEL_IDC_6_0, + e6_1 = STD_VIDEO_H265_LEVEL_IDC_6_1, + e6_2 = STD_VIDEO_H265_LEVEL_IDC_6_2, + eInvalid = STD_VIDEO_H265_LEVEL_IDC_INVALID + }; + + enum class H265SliceType + { + eB = STD_VIDEO_H265_SLICE_TYPE_B, + eP = STD_VIDEO_H265_SLICE_TYPE_P, + eI = STD_VIDEO_H265_SLICE_TYPE_I, + eInvalid = STD_VIDEO_H265_SLICE_TYPE_INVALID + }; + + enum class H265PictureType + { + eP = STD_VIDEO_H265_PICTURE_TYPE_P, + eB = STD_VIDEO_H265_PICTURE_TYPE_B, + eI = STD_VIDEO_H265_PICTURE_TYPE_I, + eIdr = STD_VIDEO_H265_PICTURE_TYPE_IDR, + eInvalid = STD_VIDEO_H265_PICTURE_TYPE_INVALID + }; + + enum class H265AspectRatioIdc + { + eUnspecified = STD_VIDEO_H265_ASPECT_RATIO_IDC_UNSPECIFIED, + eSquare = STD_VIDEO_H265_ASPECT_RATIO_IDC_SQUARE, + e12_11 = STD_VIDEO_H265_ASPECT_RATIO_IDC_12_11, + e10_11 = STD_VIDEO_H265_ASPECT_RATIO_IDC_10_11, + e16_11 = STD_VIDEO_H265_ASPECT_RATIO_IDC_16_11, + e40_33 = STD_VIDEO_H265_ASPECT_RATIO_IDC_40_33, + e24_11 = STD_VIDEO_H265_ASPECT_RATIO_IDC_24_11, + e20_11 = STD_VIDEO_H265_ASPECT_RATIO_IDC_20_11, + e32_11 = STD_VIDEO_H265_ASPECT_RATIO_IDC_32_11, + e80_33 = STD_VIDEO_H265_ASPECT_RATIO_IDC_80_33, + e18_11 = STD_VIDEO_H265_ASPECT_RATIO_IDC_18_11, + e15_11 = STD_VIDEO_H265_ASPECT_RATIO_IDC_15_11, + e64_33 = STD_VIDEO_H265_ASPECT_RATIO_IDC_64_33, + e160_99 = STD_VIDEO_H265_ASPECT_RATIO_IDC_160_99, + e4_3 = STD_VIDEO_H265_ASPECT_RATIO_IDC_4_3, + e3_2 = STD_VIDEO_H265_ASPECT_RATIO_IDC_3_2, + e2_1 = STD_VIDEO_H265_ASPECT_RATIO_IDC_2_1, + eExtendedSar = STD_VIDEO_H265_ASPECT_RATIO_IDC_EXTENDED_SAR, + eInvalid = STD_VIDEO_H265_ASPECT_RATIO_IDC_INVALID + }; + + //=== vulkan_video_codec_av1std === + + enum class AV1Profile + { + eMain = STD_VIDEO_AV1_PROFILE_MAIN, + eHigh = STD_VIDEO_AV1_PROFILE_HIGH, + eProfessional = STD_VIDEO_AV1_PROFILE_PROFESSIONAL, + eInvalid = STD_VIDEO_AV1_PROFILE_INVALID + }; + + enum class AV1Level + { + e2_0 = STD_VIDEO_AV1_LEVEL_2_0, + e2_1 = STD_VIDEO_AV1_LEVEL_2_1, + e2_2 = STD_VIDEO_AV1_LEVEL_2_2, + e2_3 = STD_VIDEO_AV1_LEVEL_2_3, + e3_0 = STD_VIDEO_AV1_LEVEL_3_0, + e3_1 = STD_VIDEO_AV1_LEVEL_3_1, + e3_2 = STD_VIDEO_AV1_LEVEL_3_2, + e3_3 = STD_VIDEO_AV1_LEVEL_3_3, + e4_0 = STD_VIDEO_AV1_LEVEL_4_0, + e4_1 = STD_VIDEO_AV1_LEVEL_4_1, + e4_2 = STD_VIDEO_AV1_LEVEL_4_2, + e4_3 = STD_VIDEO_AV1_LEVEL_4_3, + e5_0 = STD_VIDEO_AV1_LEVEL_5_0, + e5_1 = STD_VIDEO_AV1_LEVEL_5_1, + e5_2 = STD_VIDEO_AV1_LEVEL_5_2, + e5_3 = STD_VIDEO_AV1_LEVEL_5_3, + e6_0 = STD_VIDEO_AV1_LEVEL_6_0, + e6_1 = STD_VIDEO_AV1_LEVEL_6_1, + e6_2 = STD_VIDEO_AV1_LEVEL_6_2, + e6_3 = STD_VIDEO_AV1_LEVEL_6_3, + e7_0 = STD_VIDEO_AV1_LEVEL_7_0, + e7_1 = STD_VIDEO_AV1_LEVEL_7_1, + e7_2 = STD_VIDEO_AV1_LEVEL_7_2, + e7_3 = STD_VIDEO_AV1_LEVEL_7_3, + eInvalid = STD_VIDEO_AV1_LEVEL_INVALID + }; + + enum class AV1FrameType + { + eKey = STD_VIDEO_AV1_FRAME_TYPE_KEY, + eInter = STD_VIDEO_AV1_FRAME_TYPE_INTER, + eIntraOnly = STD_VIDEO_AV1_FRAME_TYPE_INTRA_ONLY, + eSwitch = STD_VIDEO_AV1_FRAME_TYPE_SWITCH, + eInvalid = STD_VIDEO_AV1_FRAME_TYPE_INVALID + }; + + enum class AV1ReferenceName + { + eIntraFrame = STD_VIDEO_AV1_REFERENCE_NAME_INTRA_FRAME, + eLastFrame = STD_VIDEO_AV1_REFERENCE_NAME_LAST_FRAME, + eLast2Frame = STD_VIDEO_AV1_REFERENCE_NAME_LAST2_FRAME, + eLast3Frame = STD_VIDEO_AV1_REFERENCE_NAME_LAST3_FRAME, + eGoldenFrame = STD_VIDEO_AV1_REFERENCE_NAME_GOLDEN_FRAME, + eBwdrefFrame = STD_VIDEO_AV1_REFERENCE_NAME_BWDREF_FRAME, + eAltref2Frame = STD_VIDEO_AV1_REFERENCE_NAME_ALTREF2_FRAME, + eAltrefFrame = STD_VIDEO_AV1_REFERENCE_NAME_ALTREF_FRAME, + eInvalid = STD_VIDEO_AV1_REFERENCE_NAME_INVALID + }; + + enum class AV1InterpolationFilter + { + eEighttap = STD_VIDEO_AV1_INTERPOLATION_FILTER_EIGHTTAP, + eEighttapSmooth = STD_VIDEO_AV1_INTERPOLATION_FILTER_EIGHTTAP_SMOOTH, + eEighttapSharp = STD_VIDEO_AV1_INTERPOLATION_FILTER_EIGHTTAP_SHARP, + eBilinear = STD_VIDEO_AV1_INTERPOLATION_FILTER_BILINEAR, + eSwitchable = STD_VIDEO_AV1_INTERPOLATION_FILTER_SWITCHABLE, + eInvalid = STD_VIDEO_AV1_INTERPOLATION_FILTER_INVALID + }; + + enum class AV1TxMode + { + eOnly4X4 = STD_VIDEO_AV1_TX_MODE_ONLY_4X4, + eLargest = STD_VIDEO_AV1_TX_MODE_LARGEST, + eSelect = STD_VIDEO_AV1_TX_MODE_SELECT, + eInvalid = STD_VIDEO_AV1_TX_MODE_INVALID + }; + + enum class AV1FrameRestorationType + { + eNone = STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_NONE, + eWiener = STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_WIENER, + eSgrproj = STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_SGRPROJ, + eSwitchable = STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_SWITCHABLE, + eInvalid = STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_INVALID + }; + + enum class AV1ColorPrimaries + { + eBt709 = STD_VIDEO_AV1_COLOR_PRIMARIES_BT_709, + eBtUnspecified = STD_VIDEO_AV1_COLOR_PRIMARIES_BT_UNSPECIFIED, + eBt470M = STD_VIDEO_AV1_COLOR_PRIMARIES_BT_470_M, + eBt470BG = STD_VIDEO_AV1_COLOR_PRIMARIES_BT_470_B_G, + eBt601 = STD_VIDEO_AV1_COLOR_PRIMARIES_BT_601, + eSmpte240 = STD_VIDEO_AV1_COLOR_PRIMARIES_SMPTE_240, + eGenericFilm = STD_VIDEO_AV1_COLOR_PRIMARIES_GENERIC_FILM, + eBt2020 = STD_VIDEO_AV1_COLOR_PRIMARIES_BT_2020, + eXyz = STD_VIDEO_AV1_COLOR_PRIMARIES_XYZ, + eSmpte431 = STD_VIDEO_AV1_COLOR_PRIMARIES_SMPTE_431, + eSmpte432 = STD_VIDEO_AV1_COLOR_PRIMARIES_SMPTE_432, + eEbu3213 = STD_VIDEO_AV1_COLOR_PRIMARIES_EBU_3213, + eInvalid = STD_VIDEO_AV1_COLOR_PRIMARIES_INVALID + }; + + enum class AV1TransferCharacteristics + { + eReserved0 = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_RESERVED_0, + eBt709 = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_709, + eUnspecified = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_UNSPECIFIED, + eReserved3 = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_RESERVED_3, + eBt470M = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_470_M, + eBt470BG = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_470_B_G, + eBt601 = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_601, + eSmpte240 = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_SMPTE_240, + eLinear = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_LINEAR, + eLog100 = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_LOG_100, + eLog100Sqrt10 = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_LOG_100_SQRT10, + eIec61966 = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_IEC_61966, + eBt1361 = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_1361, + eSrgb = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_SRGB, + eBt2020_10Bit = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_2020_10_BIT, + eBt2020_12Bit = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_2020_12_BIT, + eSmpte2084 = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_SMPTE_2084, + eSmpte428 = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_SMPTE_428, + eHlg = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_HLG, + eInvalid = STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_INVALID + }; + + enum class AV1MatrixCoefficients + { + eIdentity = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_IDENTITY, + eBt709 = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_BT_709, + eUnspecified = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_UNSPECIFIED, + eReserved3 = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_RESERVED_3, + eFcc = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_FCC, + eBt470BG = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_BT_470_B_G, + eBt601 = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_BT_601, + eSmpte240 = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_SMPTE_240, + eSmpteYcgco = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_SMPTE_YCGCO, + eBt2020Ncl = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_BT_2020_NCL, + eBt2020Cl = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_BT_2020_CL, + eSmpte2085 = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_SMPTE_2085, + eChromatNcl = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_CHROMAT_NCL, + eChromatCl = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_CHROMAT_CL, + eIctcp = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_ICTCP, + eInvalid = STD_VIDEO_AV1_MATRIX_COEFFICIENTS_INVALID + }; + + enum class AV1ChromaSamplePosition + { + eUnknown = STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_UNKNOWN, + eVertical = STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_VERTICAL, + eColocated = STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_COLOCATED, + eReserved = STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_RESERVED, + eInvalid = STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_INVALID + }; + + //=============== + //=== STRUCTS === + //=============== + + //=== vulkan_video_codec_h264std === + + struct H264SpsVuiFlags + { + using NativeType = StdVideoH264SpsVuiFlags; + + operator StdVideoH264SpsVuiFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH264SpsVuiFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H264SpsVuiFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( aspect_ratio_info_present_flag == rhs.aspect_ratio_info_present_flag ) && ( overscan_info_present_flag == rhs.overscan_info_present_flag ) && + ( overscan_appropriate_flag == rhs.overscan_appropriate_flag ) && ( video_signal_type_present_flag == rhs.video_signal_type_present_flag ) && + ( video_full_range_flag == rhs.video_full_range_flag ) && ( color_description_present_flag == rhs.color_description_present_flag ) && + ( chroma_loc_info_present_flag == rhs.chroma_loc_info_present_flag ) && ( timing_info_present_flag == rhs.timing_info_present_flag ) && + ( fixed_frame_rate_flag == rhs.fixed_frame_rate_flag ) && ( bitstream_restriction_flag == rhs.bitstream_restriction_flag ) && + ( nal_hrd_parameters_present_flag == rhs.nal_hrd_parameters_present_flag ) && + ( vcl_hrd_parameters_present_flag == rhs.vcl_hrd_parameters_present_flag ); + } + + bool operator!=( H264SpsVuiFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t aspect_ratio_info_present_flag : 1; + uint32_t overscan_info_present_flag : 1; + uint32_t overscan_appropriate_flag : 1; + uint32_t video_signal_type_present_flag : 1; + uint32_t video_full_range_flag : 1; + uint32_t color_description_present_flag : 1; + uint32_t chroma_loc_info_present_flag : 1; + uint32_t timing_info_present_flag : 1; + uint32_t fixed_frame_rate_flag : 1; + uint32_t bitstream_restriction_flag : 1; + uint32_t nal_hrd_parameters_present_flag : 1; + uint32_t vcl_hrd_parameters_present_flag : 1; + }; + + struct H264HrdParameters + { + using NativeType = StdVideoH264HrdParameters; + + operator StdVideoH264HrdParameters const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH264HrdParameters &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H264HrdParameters const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( cpb_cnt_minus1 == rhs.cpb_cnt_minus1 ) && ( bit_rate_scale == rhs.bit_rate_scale ) && ( cpb_size_scale == rhs.cpb_size_scale ) && + ( reserved1 == rhs.reserved1 ) && ( bit_rate_value_minus1 == rhs.bit_rate_value_minus1 ) && + ( cpb_size_value_minus1 == rhs.cpb_size_value_minus1 ) && ( cbr_flag == rhs.cbr_flag ) && + ( initial_cpb_removal_delay_length_minus1 == rhs.initial_cpb_removal_delay_length_minus1 ) && + ( cpb_removal_delay_length_minus1 == rhs.cpb_removal_delay_length_minus1 ) && + ( dpb_output_delay_length_minus1 == rhs.dpb_output_delay_length_minus1 ) && ( time_offset_length == rhs.time_offset_length ); + } + + bool operator!=( H264HrdParameters const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint8_t cpb_cnt_minus1 = {}; + uint8_t bit_rate_scale = {}; + uint8_t cpb_size_scale = {}; + uint8_t reserved1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D bit_rate_value_minus1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D cpb_size_value_minus1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D cbr_flag = {}; + uint32_t initial_cpb_removal_delay_length_minus1 = {}; + uint32_t cpb_removal_delay_length_minus1 = {}; + uint32_t dpb_output_delay_length_minus1 = {}; + uint32_t time_offset_length = {}; + }; + + struct H264SequenceParameterSetVui + { + using NativeType = StdVideoH264SequenceParameterSetVui; + + operator StdVideoH264SequenceParameterSetVui const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH264SequenceParameterSetVui &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H264SequenceParameterSetVui const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( aspect_ratio_idc == rhs.aspect_ratio_idc ) && ( sar_width == rhs.sar_width ) && ( sar_height == rhs.sar_height ) && + ( video_format == rhs.video_format ) && ( colour_primaries == rhs.colour_primaries ) && + ( transfer_characteristics == rhs.transfer_characteristics ) && ( matrix_coefficients == rhs.matrix_coefficients ) && + ( num_units_in_tick == rhs.num_units_in_tick ) && ( time_scale == rhs.time_scale ) && ( max_num_reorder_frames == rhs.max_num_reorder_frames ) && + ( max_dec_frame_buffering == rhs.max_dec_frame_buffering ) && ( chroma_sample_loc_type_top_field == rhs.chroma_sample_loc_type_top_field ) && + ( chroma_sample_loc_type_bottom_field == rhs.chroma_sample_loc_type_bottom_field ) && ( reserved1 == rhs.reserved1 ) && + ( pHrdParameters == rhs.pHrdParameters ); + } + + bool operator!=( H264SequenceParameterSetVui const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264SpsVuiFlags flags = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264AspectRatioIdc aspect_ratio_idc = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264AspectRatioIdc::eUnspecified; + uint16_t sar_width = {}; + uint16_t sar_height = {}; + uint8_t video_format = {}; + uint8_t colour_primaries = {}; + uint8_t transfer_characteristics = {}; + uint8_t matrix_coefficients = {}; + uint32_t num_units_in_tick = {}; + uint32_t time_scale = {}; + uint8_t max_num_reorder_frames = {}; + uint8_t max_dec_frame_buffering = {}; + uint8_t chroma_sample_loc_type_top_field = {}; + uint8_t chroma_sample_loc_type_bottom_field = {}; + uint32_t reserved1 = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264HrdParameters * pHrdParameters = {}; + }; + + struct H264SpsFlags + { + using NativeType = StdVideoH264SpsFlags; + + operator StdVideoH264SpsFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH264SpsFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H264SpsFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( constraint_set0_flag == rhs.constraint_set0_flag ) && ( constraint_set1_flag == rhs.constraint_set1_flag ) && + ( constraint_set2_flag == rhs.constraint_set2_flag ) && ( constraint_set3_flag == rhs.constraint_set3_flag ) && + ( constraint_set4_flag == rhs.constraint_set4_flag ) && ( constraint_set5_flag == rhs.constraint_set5_flag ) && + ( direct_8x8_inference_flag == rhs.direct_8x8_inference_flag ) && ( mb_adaptive_frame_field_flag == rhs.mb_adaptive_frame_field_flag ) && + ( frame_mbs_only_flag == rhs.frame_mbs_only_flag ) && ( delta_pic_order_always_zero_flag == rhs.delta_pic_order_always_zero_flag ) && + ( separate_colour_plane_flag == rhs.separate_colour_plane_flag ) && + ( gaps_in_frame_num_value_allowed_flag == rhs.gaps_in_frame_num_value_allowed_flag ) && + ( qpprime_y_zero_transform_bypass_flag == rhs.qpprime_y_zero_transform_bypass_flag ) && ( frame_cropping_flag == rhs.frame_cropping_flag ) && + ( seq_scaling_matrix_present_flag == rhs.seq_scaling_matrix_present_flag ) && ( vui_parameters_present_flag == rhs.vui_parameters_present_flag ); + } + + bool operator!=( H264SpsFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t constraint_set0_flag : 1; + uint32_t constraint_set1_flag : 1; + uint32_t constraint_set2_flag : 1; + uint32_t constraint_set3_flag : 1; + uint32_t constraint_set4_flag : 1; + uint32_t constraint_set5_flag : 1; + uint32_t direct_8x8_inference_flag : 1; + uint32_t mb_adaptive_frame_field_flag : 1; + uint32_t frame_mbs_only_flag : 1; + uint32_t delta_pic_order_always_zero_flag : 1; + uint32_t separate_colour_plane_flag : 1; + uint32_t gaps_in_frame_num_value_allowed_flag : 1; + uint32_t qpprime_y_zero_transform_bypass_flag : 1; + uint32_t frame_cropping_flag : 1; + uint32_t seq_scaling_matrix_present_flag : 1; + uint32_t vui_parameters_present_flag : 1; + }; + + struct H264ScalingLists + { + using NativeType = StdVideoH264ScalingLists; + + operator StdVideoH264ScalingLists const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH264ScalingLists &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H264ScalingLists const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( scaling_list_present_mask == rhs.scaling_list_present_mask ) && ( use_default_scaling_matrix_mask == rhs.use_default_scaling_matrix_mask ) && + ( ScalingList4x4 == rhs.ScalingList4x4 ) && ( ScalingList8x8 == rhs.ScalingList8x8 ); + } + + bool operator!=( H264ScalingLists const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint16_t scaling_list_present_mask = {}; + uint16_t use_default_scaling_matrix_mask = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper2D + ScalingList4x4 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper2D + ScalingList8x8 = {}; + }; + + struct H264SequenceParameterSet + { + using NativeType = StdVideoH264SequenceParameterSet; + + operator StdVideoH264SequenceParameterSet const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH264SequenceParameterSet &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H264SequenceParameterSet const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( profile_idc == rhs.profile_idc ) && ( level_idc == rhs.level_idc ) && + ( chroma_format_idc == rhs.chroma_format_idc ) && ( seq_parameter_set_id == rhs.seq_parameter_set_id ) && + ( bit_depth_luma_minus8 == rhs.bit_depth_luma_minus8 ) && ( bit_depth_chroma_minus8 == rhs.bit_depth_chroma_minus8 ) && + ( log2_max_frame_num_minus4 == rhs.log2_max_frame_num_minus4 ) && ( pic_order_cnt_type == rhs.pic_order_cnt_type ) && + ( offset_for_non_ref_pic == rhs.offset_for_non_ref_pic ) && ( offset_for_top_to_bottom_field == rhs.offset_for_top_to_bottom_field ) && + ( log2_max_pic_order_cnt_lsb_minus4 == rhs.log2_max_pic_order_cnt_lsb_minus4 ) && + ( num_ref_frames_in_pic_order_cnt_cycle == rhs.num_ref_frames_in_pic_order_cnt_cycle ) && ( max_num_ref_frames == rhs.max_num_ref_frames ) && + ( reserved1 == rhs.reserved1 ) && ( pic_width_in_mbs_minus1 == rhs.pic_width_in_mbs_minus1 ) && + ( pic_height_in_map_units_minus1 == rhs.pic_height_in_map_units_minus1 ) && ( frame_crop_left_offset == rhs.frame_crop_left_offset ) && + ( frame_crop_right_offset == rhs.frame_crop_right_offset ) && ( frame_crop_top_offset == rhs.frame_crop_top_offset ) && + ( frame_crop_bottom_offset == rhs.frame_crop_bottom_offset ) && ( reserved2 == rhs.reserved2 ) && + ( pOffsetForRefFrame == rhs.pOffsetForRefFrame ) && ( pScalingLists == rhs.pScalingLists ) && + ( pSequenceParameterSetVui == rhs.pSequenceParameterSetVui ); + } + + bool operator!=( H264SequenceParameterSet const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264SpsFlags flags = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264ProfileIdc profile_idc = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264ProfileIdc::eBaseline; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264LevelIdc level_idc = VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264LevelIdc::e1_0; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264ChromaFormatIdc chroma_format_idc = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264ChromaFormatIdc::eMonochrome; + uint8_t seq_parameter_set_id = {}; + uint8_t bit_depth_luma_minus8 = {}; + uint8_t bit_depth_chroma_minus8 = {}; + uint8_t log2_max_frame_num_minus4 = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264PocType pic_order_cnt_type = VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264PocType::e0; + int32_t offset_for_non_ref_pic = {}; + int32_t offset_for_top_to_bottom_field = {}; + uint8_t log2_max_pic_order_cnt_lsb_minus4 = {}; + uint8_t num_ref_frames_in_pic_order_cnt_cycle = {}; + uint8_t max_num_ref_frames = {}; + uint8_t reserved1 = {}; + uint32_t pic_width_in_mbs_minus1 = {}; + uint32_t pic_height_in_map_units_minus1 = {}; + uint32_t frame_crop_left_offset = {}; + uint32_t frame_crop_right_offset = {}; + uint32_t frame_crop_top_offset = {}; + uint32_t frame_crop_bottom_offset = {}; + uint32_t reserved2 = {}; + const int32_t * pOffsetForRefFrame = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264ScalingLists * pScalingLists = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264SequenceParameterSetVui * pSequenceParameterSetVui = {}; + }; + + struct H264PpsFlags + { + using NativeType = StdVideoH264PpsFlags; + + operator StdVideoH264PpsFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH264PpsFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H264PpsFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( transform_8x8_mode_flag == rhs.transform_8x8_mode_flag ) && ( redundant_pic_cnt_present_flag == rhs.redundant_pic_cnt_present_flag ) && + ( constrained_intra_pred_flag == rhs.constrained_intra_pred_flag ) && + ( deblocking_filter_control_present_flag == rhs.deblocking_filter_control_present_flag ) && ( weighted_pred_flag == rhs.weighted_pred_flag ) && + ( bottom_field_pic_order_in_frame_present_flag == rhs.bottom_field_pic_order_in_frame_present_flag ) && + ( entropy_coding_mode_flag == rhs.entropy_coding_mode_flag ) && ( pic_scaling_matrix_present_flag == rhs.pic_scaling_matrix_present_flag ); + } + + bool operator!=( H264PpsFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t transform_8x8_mode_flag : 1; + uint32_t redundant_pic_cnt_present_flag : 1; + uint32_t constrained_intra_pred_flag : 1; + uint32_t deblocking_filter_control_present_flag : 1; + uint32_t weighted_pred_flag : 1; + uint32_t bottom_field_pic_order_in_frame_present_flag : 1; + uint32_t entropy_coding_mode_flag : 1; + uint32_t pic_scaling_matrix_present_flag : 1; + }; + + struct H264PictureParameterSet + { + using NativeType = StdVideoH264PictureParameterSet; + + operator StdVideoH264PictureParameterSet const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH264PictureParameterSet &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H264PictureParameterSet const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( seq_parameter_set_id == rhs.seq_parameter_set_id ) && ( pic_parameter_set_id == rhs.pic_parameter_set_id ) && + ( num_ref_idx_l0_default_active_minus1 == rhs.num_ref_idx_l0_default_active_minus1 ) && + ( num_ref_idx_l1_default_active_minus1 == rhs.num_ref_idx_l1_default_active_minus1 ) && ( weighted_bipred_idc == rhs.weighted_bipred_idc ) && + ( pic_init_qp_minus26 == rhs.pic_init_qp_minus26 ) && ( pic_init_qs_minus26 == rhs.pic_init_qs_minus26 ) && + ( chroma_qp_index_offset == rhs.chroma_qp_index_offset ) && ( second_chroma_qp_index_offset == rhs.second_chroma_qp_index_offset ) && + ( pScalingLists == rhs.pScalingLists ); + } + + bool operator!=( H264PictureParameterSet const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264PpsFlags flags = {}; + uint8_t seq_parameter_set_id = {}; + uint8_t pic_parameter_set_id = {}; + uint8_t num_ref_idx_l0_default_active_minus1 = {}; + uint8_t num_ref_idx_l1_default_active_minus1 = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264WeightedBipredIdc weighted_bipred_idc = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264WeightedBipredIdc::eDefault; + int8_t pic_init_qp_minus26 = {}; + int8_t pic_init_qs_minus26 = {}; + int8_t chroma_qp_index_offset = {}; + int8_t second_chroma_qp_index_offset = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264ScalingLists * pScalingLists = {}; + }; + + //=== vulkan_video_codec_h264std_decode === + + struct DecodeH264PictureInfoFlags + { + using NativeType = StdVideoDecodeH264PictureInfoFlags; + + operator StdVideoDecodeH264PictureInfoFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoDecodeH264PictureInfoFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( DecodeH264PictureInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( field_pic_flag == rhs.field_pic_flag ) && ( is_intra == rhs.is_intra ) && ( IdrPicFlag == rhs.IdrPicFlag ) && + ( bottom_field_flag == rhs.bottom_field_flag ) && ( is_reference == rhs.is_reference ) && + ( complementary_field_pair == rhs.complementary_field_pair ); + } + + bool operator!=( DecodeH264PictureInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t field_pic_flag : 1; + uint32_t is_intra : 1; + uint32_t IdrPicFlag : 1; + uint32_t bottom_field_flag : 1; + uint32_t is_reference : 1; + uint32_t complementary_field_pair : 1; + }; + + struct DecodeH264PictureInfo + { + using NativeType = StdVideoDecodeH264PictureInfo; + + operator StdVideoDecodeH264PictureInfo const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoDecodeH264PictureInfo &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( DecodeH264PictureInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( seq_parameter_set_id == rhs.seq_parameter_set_id ) && ( pic_parameter_set_id == rhs.pic_parameter_set_id ) && + ( reserved1 == rhs.reserved1 ) && ( reserved2 == rhs.reserved2 ) && ( frame_num == rhs.frame_num ) && ( idr_pic_id == rhs.idr_pic_id ) && + ( PicOrderCnt == rhs.PicOrderCnt ); + } + + bool operator!=( DecodeH264PictureInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::DecodeH264PictureInfoFlags flags = {}; + uint8_t seq_parameter_set_id = {}; + uint8_t pic_parameter_set_id = {}; + uint8_t reserved1 = {}; + uint8_t reserved2 = {}; + uint16_t frame_num = {}; + uint16_t idr_pic_id = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D PicOrderCnt = {}; + }; + + struct DecodeH264ReferenceInfoFlags + { + using NativeType = StdVideoDecodeH264ReferenceInfoFlags; + + operator StdVideoDecodeH264ReferenceInfoFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoDecodeH264ReferenceInfoFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( DecodeH264ReferenceInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( top_field_flag == rhs.top_field_flag ) && ( bottom_field_flag == rhs.bottom_field_flag ) && + ( used_for_long_term_reference == rhs.used_for_long_term_reference ) && ( is_non_existing == rhs.is_non_existing ); + } + + bool operator!=( DecodeH264ReferenceInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t top_field_flag : 1; + uint32_t bottom_field_flag : 1; + uint32_t used_for_long_term_reference : 1; + uint32_t is_non_existing : 1; + }; + + struct DecodeH264ReferenceInfo + { + using NativeType = StdVideoDecodeH264ReferenceInfo; + + operator StdVideoDecodeH264ReferenceInfo const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoDecodeH264ReferenceInfo &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( DecodeH264ReferenceInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( FrameNum == rhs.FrameNum ) && ( reserved == rhs.reserved ) && ( PicOrderCnt == rhs.PicOrderCnt ); + } + + bool operator!=( DecodeH264ReferenceInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::DecodeH264ReferenceInfoFlags flags = {}; + uint16_t FrameNum = {}; + uint16_t reserved = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D PicOrderCnt = {}; + }; + + //=== vulkan_video_codec_h264std_encode === + + struct EncodeH264WeightTableFlags + { + using NativeType = StdVideoEncodeH264WeightTableFlags; + + operator StdVideoEncodeH264WeightTableFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH264WeightTableFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH264WeightTableFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( luma_weight_l0_flag == rhs.luma_weight_l0_flag ) && ( chroma_weight_l0_flag == rhs.chroma_weight_l0_flag ) && + ( luma_weight_l1_flag == rhs.luma_weight_l1_flag ) && ( chroma_weight_l1_flag == rhs.chroma_weight_l1_flag ); + } + + bool operator!=( EncodeH264WeightTableFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t luma_weight_l0_flag = {}; + uint32_t chroma_weight_l0_flag = {}; + uint32_t luma_weight_l1_flag = {}; + uint32_t chroma_weight_l1_flag = {}; + }; + + struct EncodeH264WeightTable + { + using NativeType = StdVideoEncodeH264WeightTable; + + operator StdVideoEncodeH264WeightTable const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH264WeightTable &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH264WeightTable const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( luma_log2_weight_denom == rhs.luma_log2_weight_denom ) && + ( chroma_log2_weight_denom == rhs.chroma_log2_weight_denom ) && ( luma_weight_l0 == rhs.luma_weight_l0 ) && + ( luma_offset_l0 == rhs.luma_offset_l0 ) && ( chroma_weight_l0 == rhs.chroma_weight_l0 ) && ( chroma_offset_l0 == rhs.chroma_offset_l0 ) && + ( luma_weight_l1 == rhs.luma_weight_l1 ) && ( luma_offset_l1 == rhs.luma_offset_l1 ) && ( chroma_weight_l1 == rhs.chroma_weight_l1 ) && + ( chroma_offset_l1 == rhs.chroma_offset_l1 ); + } + + bool operator!=( EncodeH264WeightTable const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH264WeightTableFlags flags = {}; + uint8_t luma_log2_weight_denom = {}; + uint8_t chroma_log2_weight_denom = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D luma_weight_l0 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D luma_offset_l0 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper2D chroma_weight_l0 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper2D chroma_offset_l0 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D luma_weight_l1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D luma_offset_l1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper2D chroma_weight_l1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper2D chroma_offset_l1 = {}; + }; + + struct EncodeH264SliceHeaderFlags + { + using NativeType = StdVideoEncodeH264SliceHeaderFlags; + + operator StdVideoEncodeH264SliceHeaderFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH264SliceHeaderFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH264SliceHeaderFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( direct_spatial_mv_pred_flag == rhs.direct_spatial_mv_pred_flag ) && + ( num_ref_idx_active_override_flag == rhs.num_ref_idx_active_override_flag ) && ( reserved == rhs.reserved ); + } + + bool operator!=( EncodeH264SliceHeaderFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t direct_spatial_mv_pred_flag : 1; + uint32_t num_ref_idx_active_override_flag : 1; + uint32_t reserved : 30; + }; + + struct EncodeH264PictureInfoFlags + { + using NativeType = StdVideoEncodeH264PictureInfoFlags; + + operator StdVideoEncodeH264PictureInfoFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH264PictureInfoFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH264PictureInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( IdrPicFlag == rhs.IdrPicFlag ) && ( is_reference == rhs.is_reference ) && + ( no_output_of_prior_pics_flag == rhs.no_output_of_prior_pics_flag ) && ( long_term_reference_flag == rhs.long_term_reference_flag ) && + ( adaptive_ref_pic_marking_mode_flag == rhs.adaptive_ref_pic_marking_mode_flag ) && ( reserved == rhs.reserved ); + } + + bool operator!=( EncodeH264PictureInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t IdrPicFlag : 1; + uint32_t is_reference : 1; + uint32_t no_output_of_prior_pics_flag : 1; + uint32_t long_term_reference_flag : 1; + uint32_t adaptive_ref_pic_marking_mode_flag : 1; + uint32_t reserved : 27; + }; + + struct EncodeH264ReferenceInfoFlags + { + using NativeType = StdVideoEncodeH264ReferenceInfoFlags; + + operator StdVideoEncodeH264ReferenceInfoFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH264ReferenceInfoFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH264ReferenceInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( used_for_long_term_reference == rhs.used_for_long_term_reference ) && ( reserved == rhs.reserved ); + } + + bool operator!=( EncodeH264ReferenceInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t used_for_long_term_reference : 1; + uint32_t reserved : 31; + }; + + struct EncodeH264ReferenceListsInfoFlags + { + using NativeType = StdVideoEncodeH264ReferenceListsInfoFlags; + + operator StdVideoEncodeH264ReferenceListsInfoFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH264ReferenceListsInfoFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH264ReferenceListsInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( ref_pic_list_modification_flag_l0 == rhs.ref_pic_list_modification_flag_l0 ) && + ( ref_pic_list_modification_flag_l1 == rhs.ref_pic_list_modification_flag_l1 ) && ( reserved == rhs.reserved ); + } + + bool operator!=( EncodeH264ReferenceListsInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t ref_pic_list_modification_flag_l0 : 1; + uint32_t ref_pic_list_modification_flag_l1 : 1; + uint32_t reserved : 30; + }; + + struct EncodeH264RefListModEntry + { + using NativeType = StdVideoEncodeH264RefListModEntry; + + operator StdVideoEncodeH264RefListModEntry const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH264RefListModEntry &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH264RefListModEntry const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( modification_of_pic_nums_idc == rhs.modification_of_pic_nums_idc ) && ( abs_diff_pic_num_minus1 == rhs.abs_diff_pic_num_minus1 ) && + ( long_term_pic_num == rhs.long_term_pic_num ); + } + + bool operator!=( EncodeH264RefListModEntry const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264ModificationOfPicNumsIdc modification_of_pic_nums_idc = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264ModificationOfPicNumsIdc::eShortTermSubtract; + uint16_t abs_diff_pic_num_minus1 = {}; + uint16_t long_term_pic_num = {}; + }; + + struct EncodeH264RefPicMarkingEntry + { + using NativeType = StdVideoEncodeH264RefPicMarkingEntry; + + operator StdVideoEncodeH264RefPicMarkingEntry const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH264RefPicMarkingEntry &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH264RefPicMarkingEntry const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( memory_management_control_operation == rhs.memory_management_control_operation ) && + ( difference_of_pic_nums_minus1 == rhs.difference_of_pic_nums_minus1 ) && ( long_term_pic_num == rhs.long_term_pic_num ) && + ( long_term_frame_idx == rhs.long_term_frame_idx ) && ( max_long_term_frame_idx_plus1 == rhs.max_long_term_frame_idx_plus1 ); + } + + bool operator!=( EncodeH264RefPicMarkingEntry const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264MemMgmtControlOp memory_management_control_operation = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264MemMgmtControlOp::eEnd; + uint16_t difference_of_pic_nums_minus1 = {}; + uint16_t long_term_pic_num = {}; + uint16_t long_term_frame_idx = {}; + uint16_t max_long_term_frame_idx_plus1 = {}; + }; + + struct EncodeH264ReferenceListsInfo + { + using NativeType = StdVideoEncodeH264ReferenceListsInfo; + + operator StdVideoEncodeH264ReferenceListsInfo const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH264ReferenceListsInfo &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH264ReferenceListsInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( num_ref_idx_l0_active_minus1 == rhs.num_ref_idx_l0_active_minus1 ) && + ( num_ref_idx_l1_active_minus1 == rhs.num_ref_idx_l1_active_minus1 ) && ( RefPicList0 == rhs.RefPicList0 ) && + ( RefPicList1 == rhs.RefPicList1 ) && ( refList0ModOpCount == rhs.refList0ModOpCount ) && ( refList1ModOpCount == rhs.refList1ModOpCount ) && + ( refPicMarkingOpCount == rhs.refPicMarkingOpCount ) && ( reserved1 == rhs.reserved1 ) && + ( pRefList0ModOperations == rhs.pRefList0ModOperations ) && ( pRefList1ModOperations == rhs.pRefList1ModOperations ) && + ( pRefPicMarkingOperations == rhs.pRefPicMarkingOperations ); + } + + bool operator!=( EncodeH264ReferenceListsInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH264ReferenceListsInfoFlags flags = {}; + uint8_t num_ref_idx_l0_active_minus1 = {}; + uint8_t num_ref_idx_l1_active_minus1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D RefPicList0 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D RefPicList1 = {}; + uint8_t refList0ModOpCount = {}; + uint8_t refList1ModOpCount = {}; + uint8_t refPicMarkingOpCount = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D reserved1 = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH264RefListModEntry * pRefList0ModOperations = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH264RefListModEntry * pRefList1ModOperations = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH264RefPicMarkingEntry * pRefPicMarkingOperations = {}; + }; + + struct EncodeH264PictureInfo + { + using NativeType = StdVideoEncodeH264PictureInfo; + + operator StdVideoEncodeH264PictureInfo const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH264PictureInfo &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH264PictureInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( seq_parameter_set_id == rhs.seq_parameter_set_id ) && ( pic_parameter_set_id == rhs.pic_parameter_set_id ) && + ( idr_pic_id == rhs.idr_pic_id ) && ( primary_pic_type == rhs.primary_pic_type ) && ( frame_num == rhs.frame_num ) && + ( PicOrderCnt == rhs.PicOrderCnt ) && ( temporal_id == rhs.temporal_id ) && ( reserved1 == rhs.reserved1 ) && ( pRefLists == rhs.pRefLists ); + } + + bool operator!=( EncodeH264PictureInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH264PictureInfoFlags flags = {}; + uint8_t seq_parameter_set_id = {}; + uint8_t pic_parameter_set_id = {}; + uint16_t idr_pic_id = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264PictureType primary_pic_type = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264PictureType::eP; + uint32_t frame_num = {}; + int32_t PicOrderCnt = {}; + uint8_t temporal_id = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D reserved1 = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH264ReferenceListsInfo * pRefLists = {}; + }; + + struct EncodeH264ReferenceInfo + { + using NativeType = StdVideoEncodeH264ReferenceInfo; + + operator StdVideoEncodeH264ReferenceInfo const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH264ReferenceInfo &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH264ReferenceInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( primary_pic_type == rhs.primary_pic_type ) && ( FrameNum == rhs.FrameNum ) && ( PicOrderCnt == rhs.PicOrderCnt ) && + ( long_term_pic_num == rhs.long_term_pic_num ) && ( long_term_frame_idx == rhs.long_term_frame_idx ) && ( temporal_id == rhs.temporal_id ); + } + + bool operator!=( EncodeH264ReferenceInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH264ReferenceInfoFlags flags = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264PictureType primary_pic_type = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264PictureType::eP; + uint32_t FrameNum = {}; + int32_t PicOrderCnt = {}; + uint16_t long_term_pic_num = {}; + uint16_t long_term_frame_idx = {}; + uint8_t temporal_id = {}; + }; + + struct EncodeH264SliceHeader + { + using NativeType = StdVideoEncodeH264SliceHeader; + + operator StdVideoEncodeH264SliceHeader const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH264SliceHeader &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH264SliceHeader const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( first_mb_in_slice == rhs.first_mb_in_slice ) && ( slice_type == rhs.slice_type ) && + ( slice_alpha_c0_offset_div2 == rhs.slice_alpha_c0_offset_div2 ) && ( slice_beta_offset_div2 == rhs.slice_beta_offset_div2 ) && + ( slice_qp_delta == rhs.slice_qp_delta ) && ( reserved1 == rhs.reserved1 ) && ( cabac_init_idc == rhs.cabac_init_idc ) && + ( disable_deblocking_filter_idc == rhs.disable_deblocking_filter_idc ) && ( pWeightTable == rhs.pWeightTable ); + } + + bool operator!=( EncodeH264SliceHeader const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH264SliceHeaderFlags flags = {}; + uint32_t first_mb_in_slice = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264SliceType slice_type = VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264SliceType::eP; + int8_t slice_alpha_c0_offset_div2 = {}; + int8_t slice_beta_offset_div2 = {}; + int8_t slice_qp_delta = {}; + uint8_t reserved1 = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264CabacInitIdc cabac_init_idc = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264CabacInitIdc::e0; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264DisableDeblockingFilterIdc disable_deblocking_filter_idc = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H264DisableDeblockingFilterIdc::eDisabled; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH264WeightTable * pWeightTable = {}; + }; + + //=== vulkan_video_codec_h265std === + + struct H265DecPicBufMgr + { + using NativeType = StdVideoH265DecPicBufMgr; + + operator StdVideoH265DecPicBufMgr const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265DecPicBufMgr &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265DecPicBufMgr const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( max_latency_increase_plus1 == rhs.max_latency_increase_plus1 ) && ( max_dec_pic_buffering_minus1 == rhs.max_dec_pic_buffering_minus1 ) && + ( max_num_reorder_pics == rhs.max_num_reorder_pics ); + } + + bool operator!=( H265DecPicBufMgr const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::ArrayWrapper1D max_latency_increase_plus1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D max_dec_pic_buffering_minus1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D max_num_reorder_pics = {}; + }; + + struct H265SubLayerHrdParameters + { + using NativeType = StdVideoH265SubLayerHrdParameters; + + operator StdVideoH265SubLayerHrdParameters const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265SubLayerHrdParameters &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265SubLayerHrdParameters const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( bit_rate_value_minus1 == rhs.bit_rate_value_minus1 ) && ( cpb_size_value_minus1 == rhs.cpb_size_value_minus1 ) && + ( cpb_size_du_value_minus1 == rhs.cpb_size_du_value_minus1 ) && ( bit_rate_du_value_minus1 == rhs.bit_rate_du_value_minus1 ) && + ( cbr_flag == rhs.cbr_flag ); + } + + bool operator!=( H265SubLayerHrdParameters const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::ArrayWrapper1D bit_rate_value_minus1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D cpb_size_value_minus1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D cpb_size_du_value_minus1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D bit_rate_du_value_minus1 = {}; + uint32_t cbr_flag = {}; + }; + + struct H265HrdFlags + { + using NativeType = StdVideoH265HrdFlags; + + operator StdVideoH265HrdFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265HrdFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265HrdFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( nal_hrd_parameters_present_flag == rhs.nal_hrd_parameters_present_flag ) && + ( vcl_hrd_parameters_present_flag == rhs.vcl_hrd_parameters_present_flag ) && + ( sub_pic_hrd_params_present_flag == rhs.sub_pic_hrd_params_present_flag ) && + ( sub_pic_cpb_params_in_pic_timing_sei_flag == rhs.sub_pic_cpb_params_in_pic_timing_sei_flag ) && + ( fixed_pic_rate_general_flag == rhs.fixed_pic_rate_general_flag ) && ( fixed_pic_rate_within_cvs_flag == rhs.fixed_pic_rate_within_cvs_flag ) && + ( low_delay_hrd_flag == rhs.low_delay_hrd_flag ); + } + + bool operator!=( H265HrdFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t nal_hrd_parameters_present_flag : 1; + uint32_t vcl_hrd_parameters_present_flag : 1; + uint32_t sub_pic_hrd_params_present_flag : 1; + uint32_t sub_pic_cpb_params_in_pic_timing_sei_flag : 1; + uint32_t fixed_pic_rate_general_flag : 8; + uint32_t fixed_pic_rate_within_cvs_flag : 8; + uint32_t low_delay_hrd_flag : 8; + }; + + struct H265HrdParameters + { + using NativeType = StdVideoH265HrdParameters; + + operator StdVideoH265HrdParameters const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265HrdParameters &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265HrdParameters const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( tick_divisor_minus2 == rhs.tick_divisor_minus2 ) && + ( du_cpb_removal_delay_increment_length_minus1 == rhs.du_cpb_removal_delay_increment_length_minus1 ) && + ( dpb_output_delay_du_length_minus1 == rhs.dpb_output_delay_du_length_minus1 ) && ( bit_rate_scale == rhs.bit_rate_scale ) && + ( cpb_size_scale == rhs.cpb_size_scale ) && ( cpb_size_du_scale == rhs.cpb_size_du_scale ) && + ( initial_cpb_removal_delay_length_minus1 == rhs.initial_cpb_removal_delay_length_minus1 ) && + ( au_cpb_removal_delay_length_minus1 == rhs.au_cpb_removal_delay_length_minus1 ) && + ( dpb_output_delay_length_minus1 == rhs.dpb_output_delay_length_minus1 ) && ( cpb_cnt_minus1 == rhs.cpb_cnt_minus1 ) && + ( elemental_duration_in_tc_minus1 == rhs.elemental_duration_in_tc_minus1 ) && ( reserved == rhs.reserved ) && + ( pSubLayerHrdParametersNal == rhs.pSubLayerHrdParametersNal ) && ( pSubLayerHrdParametersVcl == rhs.pSubLayerHrdParametersVcl ); + } + + bool operator!=( H265HrdParameters const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265HrdFlags flags = {}; + uint8_t tick_divisor_minus2 = {}; + uint8_t du_cpb_removal_delay_increment_length_minus1 = {}; + uint8_t dpb_output_delay_du_length_minus1 = {}; + uint8_t bit_rate_scale = {}; + uint8_t cpb_size_scale = {}; + uint8_t cpb_size_du_scale = {}; + uint8_t initial_cpb_removal_delay_length_minus1 = {}; + uint8_t au_cpb_removal_delay_length_minus1 = {}; + uint8_t dpb_output_delay_length_minus1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D cpb_cnt_minus1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D elemental_duration_in_tc_minus1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D reserved = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265SubLayerHrdParameters * pSubLayerHrdParametersNal = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265SubLayerHrdParameters * pSubLayerHrdParametersVcl = {}; + }; + + struct H265VpsFlags + { + using NativeType = StdVideoH265VpsFlags; + + operator StdVideoH265VpsFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265VpsFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265VpsFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( vps_temporal_id_nesting_flag == rhs.vps_temporal_id_nesting_flag ) && + ( vps_sub_layer_ordering_info_present_flag == rhs.vps_sub_layer_ordering_info_present_flag ) && + ( vps_timing_info_present_flag == rhs.vps_timing_info_present_flag ) && + ( vps_poc_proportional_to_timing_flag == rhs.vps_poc_proportional_to_timing_flag ); + } + + bool operator!=( H265VpsFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t vps_temporal_id_nesting_flag : 1; + uint32_t vps_sub_layer_ordering_info_present_flag : 1; + uint32_t vps_timing_info_present_flag : 1; + uint32_t vps_poc_proportional_to_timing_flag : 1; + }; + + struct H265ProfileTierLevelFlags + { + using NativeType = StdVideoH265ProfileTierLevelFlags; + + operator StdVideoH265ProfileTierLevelFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265ProfileTierLevelFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265ProfileTierLevelFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( general_tier_flag == rhs.general_tier_flag ) && ( general_progressive_source_flag == rhs.general_progressive_source_flag ) && + ( general_interlaced_source_flag == rhs.general_interlaced_source_flag ) && + ( general_non_packed_constraint_flag == rhs.general_non_packed_constraint_flag ) && + ( general_frame_only_constraint_flag == rhs.general_frame_only_constraint_flag ); + } + + bool operator!=( H265ProfileTierLevelFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t general_tier_flag : 1; + uint32_t general_progressive_source_flag : 1; + uint32_t general_interlaced_source_flag : 1; + uint32_t general_non_packed_constraint_flag : 1; + uint32_t general_frame_only_constraint_flag : 1; + }; + + struct H265ProfileTierLevel + { + using NativeType = StdVideoH265ProfileTierLevel; + + operator StdVideoH265ProfileTierLevel const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265ProfileTierLevel &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265ProfileTierLevel const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( general_profile_idc == rhs.general_profile_idc ) && ( general_level_idc == rhs.general_level_idc ); + } + + bool operator!=( H265ProfileTierLevel const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265ProfileTierLevelFlags flags = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265ProfileIdc general_profile_idc = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265ProfileIdc::eMain; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265LevelIdc general_level_idc = VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265LevelIdc::e1_0; + }; + + struct H265VideoParameterSet + { + using NativeType = StdVideoH265VideoParameterSet; + + operator StdVideoH265VideoParameterSet const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265VideoParameterSet &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265VideoParameterSet const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( vps_video_parameter_set_id == rhs.vps_video_parameter_set_id ) && + ( vps_max_sub_layers_minus1 == rhs.vps_max_sub_layers_minus1 ) && ( reserved1 == rhs.reserved1 ) && ( reserved2 == rhs.reserved2 ) && + ( vps_num_units_in_tick == rhs.vps_num_units_in_tick ) && ( vps_time_scale == rhs.vps_time_scale ) && + ( vps_num_ticks_poc_diff_one_minus1 == rhs.vps_num_ticks_poc_diff_one_minus1 ) && ( reserved3 == rhs.reserved3 ) && + ( pDecPicBufMgr == rhs.pDecPicBufMgr ) && ( pHrdParameters == rhs.pHrdParameters ) && ( pProfileTierLevel == rhs.pProfileTierLevel ); + } + + bool operator!=( H265VideoParameterSet const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265VpsFlags flags = {}; + uint8_t vps_video_parameter_set_id = {}; + uint8_t vps_max_sub_layers_minus1 = {}; + uint8_t reserved1 = {}; + uint8_t reserved2 = {}; + uint32_t vps_num_units_in_tick = {}; + uint32_t vps_time_scale = {}; + uint32_t vps_num_ticks_poc_diff_one_minus1 = {}; + uint32_t reserved3 = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265DecPicBufMgr * pDecPicBufMgr = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265HrdParameters * pHrdParameters = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265ProfileTierLevel * pProfileTierLevel = {}; + }; + + struct H265ScalingLists + { + using NativeType = StdVideoH265ScalingLists; + + operator StdVideoH265ScalingLists const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265ScalingLists &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265ScalingLists const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( ScalingList4x4 == rhs.ScalingList4x4 ) && ( ScalingList8x8 == rhs.ScalingList8x8 ) && ( ScalingList16x16 == rhs.ScalingList16x16 ) && + ( ScalingList32x32 == rhs.ScalingList32x32 ) && ( ScalingListDCCoef16x16 == rhs.ScalingListDCCoef16x16 ) && + ( ScalingListDCCoef32x32 == rhs.ScalingListDCCoef32x32 ); + } + + bool operator!=( H265ScalingLists const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::ArrayWrapper2D + ScalingList4x4 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper2D + ScalingList8x8 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper2D + ScalingList16x16 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper2D + ScalingList32x32 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D ScalingListDCCoef16x16 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D ScalingListDCCoef32x32 = {}; + }; + + struct H265SpsVuiFlags + { + using NativeType = StdVideoH265SpsVuiFlags; + + operator StdVideoH265SpsVuiFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265SpsVuiFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265SpsVuiFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( aspect_ratio_info_present_flag == rhs.aspect_ratio_info_present_flag ) && ( overscan_info_present_flag == rhs.overscan_info_present_flag ) && + ( overscan_appropriate_flag == rhs.overscan_appropriate_flag ) && ( video_signal_type_present_flag == rhs.video_signal_type_present_flag ) && + ( video_full_range_flag == rhs.video_full_range_flag ) && ( colour_description_present_flag == rhs.colour_description_present_flag ) && + ( chroma_loc_info_present_flag == rhs.chroma_loc_info_present_flag ) && + ( neutral_chroma_indication_flag == rhs.neutral_chroma_indication_flag ) && ( field_seq_flag == rhs.field_seq_flag ) && + ( frame_field_info_present_flag == rhs.frame_field_info_present_flag ) && ( default_display_window_flag == rhs.default_display_window_flag ) && + ( vui_timing_info_present_flag == rhs.vui_timing_info_present_flag ) && + ( vui_poc_proportional_to_timing_flag == rhs.vui_poc_proportional_to_timing_flag ) && + ( vui_hrd_parameters_present_flag == rhs.vui_hrd_parameters_present_flag ) && ( bitstream_restriction_flag == rhs.bitstream_restriction_flag ) && + ( tiles_fixed_structure_flag == rhs.tiles_fixed_structure_flag ) && + ( motion_vectors_over_pic_boundaries_flag == rhs.motion_vectors_over_pic_boundaries_flag ) && + ( restricted_ref_pic_lists_flag == rhs.restricted_ref_pic_lists_flag ); + } + + bool operator!=( H265SpsVuiFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t aspect_ratio_info_present_flag : 1; + uint32_t overscan_info_present_flag : 1; + uint32_t overscan_appropriate_flag : 1; + uint32_t video_signal_type_present_flag : 1; + uint32_t video_full_range_flag : 1; + uint32_t colour_description_present_flag : 1; + uint32_t chroma_loc_info_present_flag : 1; + uint32_t neutral_chroma_indication_flag : 1; + uint32_t field_seq_flag : 1; + uint32_t frame_field_info_present_flag : 1; + uint32_t default_display_window_flag : 1; + uint32_t vui_timing_info_present_flag : 1; + uint32_t vui_poc_proportional_to_timing_flag : 1; + uint32_t vui_hrd_parameters_present_flag : 1; + uint32_t bitstream_restriction_flag : 1; + uint32_t tiles_fixed_structure_flag : 1; + uint32_t motion_vectors_over_pic_boundaries_flag : 1; + uint32_t restricted_ref_pic_lists_flag : 1; + }; + + struct H265SequenceParameterSetVui + { + using NativeType = StdVideoH265SequenceParameterSetVui; + + operator StdVideoH265SequenceParameterSetVui const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265SequenceParameterSetVui &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265SequenceParameterSetVui const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( aspect_ratio_idc == rhs.aspect_ratio_idc ) && ( sar_width == rhs.sar_width ) && ( sar_height == rhs.sar_height ) && + ( video_format == rhs.video_format ) && ( colour_primaries == rhs.colour_primaries ) && + ( transfer_characteristics == rhs.transfer_characteristics ) && ( matrix_coeffs == rhs.matrix_coeffs ) && + ( chroma_sample_loc_type_top_field == rhs.chroma_sample_loc_type_top_field ) && + ( chroma_sample_loc_type_bottom_field == rhs.chroma_sample_loc_type_bottom_field ) && ( reserved1 == rhs.reserved1 ) && + ( reserved2 == rhs.reserved2 ) && ( def_disp_win_left_offset == rhs.def_disp_win_left_offset ) && + ( def_disp_win_right_offset == rhs.def_disp_win_right_offset ) && ( def_disp_win_top_offset == rhs.def_disp_win_top_offset ) && + ( def_disp_win_bottom_offset == rhs.def_disp_win_bottom_offset ) && ( vui_num_units_in_tick == rhs.vui_num_units_in_tick ) && + ( vui_time_scale == rhs.vui_time_scale ) && ( vui_num_ticks_poc_diff_one_minus1 == rhs.vui_num_ticks_poc_diff_one_minus1 ) && + ( min_spatial_segmentation_idc == rhs.min_spatial_segmentation_idc ) && ( reserved3 == rhs.reserved3 ) && + ( max_bytes_per_pic_denom == rhs.max_bytes_per_pic_denom ) && ( max_bits_per_min_cu_denom == rhs.max_bits_per_min_cu_denom ) && + ( log2_max_mv_length_horizontal == rhs.log2_max_mv_length_horizontal ) && ( log2_max_mv_length_vertical == rhs.log2_max_mv_length_vertical ) && + ( pHrdParameters == rhs.pHrdParameters ); + } + + bool operator!=( H265SequenceParameterSetVui const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265SpsVuiFlags flags = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265AspectRatioIdc aspect_ratio_idc = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265AspectRatioIdc::eUnspecified; + uint16_t sar_width = {}; + uint16_t sar_height = {}; + uint8_t video_format = {}; + uint8_t colour_primaries = {}; + uint8_t transfer_characteristics = {}; + uint8_t matrix_coeffs = {}; + uint8_t chroma_sample_loc_type_top_field = {}; + uint8_t chroma_sample_loc_type_bottom_field = {}; + uint8_t reserved1 = {}; + uint8_t reserved2 = {}; + uint16_t def_disp_win_left_offset = {}; + uint16_t def_disp_win_right_offset = {}; + uint16_t def_disp_win_top_offset = {}; + uint16_t def_disp_win_bottom_offset = {}; + uint32_t vui_num_units_in_tick = {}; + uint32_t vui_time_scale = {}; + uint32_t vui_num_ticks_poc_diff_one_minus1 = {}; + uint16_t min_spatial_segmentation_idc = {}; + uint16_t reserved3 = {}; + uint8_t max_bytes_per_pic_denom = {}; + uint8_t max_bits_per_min_cu_denom = {}; + uint8_t log2_max_mv_length_horizontal = {}; + uint8_t log2_max_mv_length_vertical = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265HrdParameters * pHrdParameters = {}; + }; + + struct H265PredictorPaletteEntries + { + using NativeType = StdVideoH265PredictorPaletteEntries; + + operator StdVideoH265PredictorPaletteEntries const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265PredictorPaletteEntries &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265PredictorPaletteEntries const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( PredictorPaletteEntries == rhs.PredictorPaletteEntries ); + } + + bool operator!=( H265PredictorPaletteEntries const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE:: + ArrayWrapper2D + PredictorPaletteEntries = {}; + }; + + struct H265SpsFlags + { + using NativeType = StdVideoH265SpsFlags; + + operator StdVideoH265SpsFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265SpsFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265SpsFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( sps_temporal_id_nesting_flag == rhs.sps_temporal_id_nesting_flag ) && ( separate_colour_plane_flag == rhs.separate_colour_plane_flag ) && + ( conformance_window_flag == rhs.conformance_window_flag ) && + ( sps_sub_layer_ordering_info_present_flag == rhs.sps_sub_layer_ordering_info_present_flag ) && + ( scaling_list_enabled_flag == rhs.scaling_list_enabled_flag ) && + ( sps_scaling_list_data_present_flag == rhs.sps_scaling_list_data_present_flag ) && ( amp_enabled_flag == rhs.amp_enabled_flag ) && + ( sample_adaptive_offset_enabled_flag == rhs.sample_adaptive_offset_enabled_flag ) && ( pcm_enabled_flag == rhs.pcm_enabled_flag ) && + ( pcm_loop_filter_disabled_flag == rhs.pcm_loop_filter_disabled_flag ) && + ( long_term_ref_pics_present_flag == rhs.long_term_ref_pics_present_flag ) && + ( sps_temporal_mvp_enabled_flag == rhs.sps_temporal_mvp_enabled_flag ) && + ( strong_intra_smoothing_enabled_flag == rhs.strong_intra_smoothing_enabled_flag ) && + ( vui_parameters_present_flag == rhs.vui_parameters_present_flag ) && ( sps_extension_present_flag == rhs.sps_extension_present_flag ) && + ( sps_range_extension_flag == rhs.sps_range_extension_flag ) && + ( transform_skip_rotation_enabled_flag == rhs.transform_skip_rotation_enabled_flag ) && + ( transform_skip_context_enabled_flag == rhs.transform_skip_context_enabled_flag ) && + ( implicit_rdpcm_enabled_flag == rhs.implicit_rdpcm_enabled_flag ) && ( explicit_rdpcm_enabled_flag == rhs.explicit_rdpcm_enabled_flag ) && + ( extended_precision_processing_flag == rhs.extended_precision_processing_flag ) && + ( intra_smoothing_disabled_flag == rhs.intra_smoothing_disabled_flag ) && + ( high_precision_offsets_enabled_flag == rhs.high_precision_offsets_enabled_flag ) && + ( persistent_rice_adaptation_enabled_flag == rhs.persistent_rice_adaptation_enabled_flag ) && + ( cabac_bypass_alignment_enabled_flag == rhs.cabac_bypass_alignment_enabled_flag ) && ( sps_scc_extension_flag == rhs.sps_scc_extension_flag ) && + ( sps_curr_pic_ref_enabled_flag == rhs.sps_curr_pic_ref_enabled_flag ) && ( palette_mode_enabled_flag == rhs.palette_mode_enabled_flag ) && + ( sps_palette_predictor_initializers_present_flag == rhs.sps_palette_predictor_initializers_present_flag ) && + ( intra_boundary_filtering_disabled_flag == rhs.intra_boundary_filtering_disabled_flag ); + } + + bool operator!=( H265SpsFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t sps_temporal_id_nesting_flag : 1; + uint32_t separate_colour_plane_flag : 1; + uint32_t conformance_window_flag : 1; + uint32_t sps_sub_layer_ordering_info_present_flag : 1; + uint32_t scaling_list_enabled_flag : 1; + uint32_t sps_scaling_list_data_present_flag : 1; + uint32_t amp_enabled_flag : 1; + uint32_t sample_adaptive_offset_enabled_flag : 1; + uint32_t pcm_enabled_flag : 1; + uint32_t pcm_loop_filter_disabled_flag : 1; + uint32_t long_term_ref_pics_present_flag : 1; + uint32_t sps_temporal_mvp_enabled_flag : 1; + uint32_t strong_intra_smoothing_enabled_flag : 1; + uint32_t vui_parameters_present_flag : 1; + uint32_t sps_extension_present_flag : 1; + uint32_t sps_range_extension_flag : 1; + uint32_t transform_skip_rotation_enabled_flag : 1; + uint32_t transform_skip_context_enabled_flag : 1; + uint32_t implicit_rdpcm_enabled_flag : 1; + uint32_t explicit_rdpcm_enabled_flag : 1; + uint32_t extended_precision_processing_flag : 1; + uint32_t intra_smoothing_disabled_flag : 1; + uint32_t high_precision_offsets_enabled_flag : 1; + uint32_t persistent_rice_adaptation_enabled_flag : 1; + uint32_t cabac_bypass_alignment_enabled_flag : 1; + uint32_t sps_scc_extension_flag : 1; + uint32_t sps_curr_pic_ref_enabled_flag : 1; + uint32_t palette_mode_enabled_flag : 1; + uint32_t sps_palette_predictor_initializers_present_flag : 1; + uint32_t intra_boundary_filtering_disabled_flag : 1; + }; + + struct H265ShortTermRefPicSetFlags + { + using NativeType = StdVideoH265ShortTermRefPicSetFlags; + + operator StdVideoH265ShortTermRefPicSetFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265ShortTermRefPicSetFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265ShortTermRefPicSetFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( inter_ref_pic_set_prediction_flag == rhs.inter_ref_pic_set_prediction_flag ) && ( delta_rps_sign == rhs.delta_rps_sign ); + } + + bool operator!=( H265ShortTermRefPicSetFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t inter_ref_pic_set_prediction_flag : 1; + uint32_t delta_rps_sign : 1; + }; + + struct H265ShortTermRefPicSet + { + using NativeType = StdVideoH265ShortTermRefPicSet; + + operator StdVideoH265ShortTermRefPicSet const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265ShortTermRefPicSet &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265ShortTermRefPicSet const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( delta_idx_minus1 == rhs.delta_idx_minus1 ) && ( use_delta_flag == rhs.use_delta_flag ) && + ( abs_delta_rps_minus1 == rhs.abs_delta_rps_minus1 ) && ( used_by_curr_pic_flag == rhs.used_by_curr_pic_flag ) && + ( used_by_curr_pic_s0_flag == rhs.used_by_curr_pic_s0_flag ) && ( used_by_curr_pic_s1_flag == rhs.used_by_curr_pic_s1_flag ) && + ( reserved1 == rhs.reserved1 ) && ( reserved2 == rhs.reserved2 ) && ( reserved3 == rhs.reserved3 ) && + ( num_negative_pics == rhs.num_negative_pics ) && ( num_positive_pics == rhs.num_positive_pics ) && + ( delta_poc_s0_minus1 == rhs.delta_poc_s0_minus1 ) && ( delta_poc_s1_minus1 == rhs.delta_poc_s1_minus1 ); + } + + bool operator!=( H265ShortTermRefPicSet const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265ShortTermRefPicSetFlags flags = {}; + uint32_t delta_idx_minus1 = {}; + uint16_t use_delta_flag = {}; + uint16_t abs_delta_rps_minus1 = {}; + uint16_t used_by_curr_pic_flag = {}; + uint16_t used_by_curr_pic_s0_flag = {}; + uint16_t used_by_curr_pic_s1_flag = {}; + uint16_t reserved1 = {}; + uint8_t reserved2 = {}; + uint8_t reserved3 = {}; + uint8_t num_negative_pics = {}; + uint8_t num_positive_pics = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D delta_poc_s0_minus1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D delta_poc_s1_minus1 = {}; + }; + + struct H265LongTermRefPicsSps + { + using NativeType = StdVideoH265LongTermRefPicsSps; + + operator StdVideoH265LongTermRefPicsSps const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265LongTermRefPicsSps &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265LongTermRefPicsSps const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( used_by_curr_pic_lt_sps_flag == rhs.used_by_curr_pic_lt_sps_flag ) && ( lt_ref_pic_poc_lsb_sps == rhs.lt_ref_pic_poc_lsb_sps ); + } + + bool operator!=( H265LongTermRefPicsSps const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t used_by_curr_pic_lt_sps_flag = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D lt_ref_pic_poc_lsb_sps = {}; + }; + + struct H265SequenceParameterSet + { + using NativeType = StdVideoH265SequenceParameterSet; + + operator StdVideoH265SequenceParameterSet const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265SequenceParameterSet &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265SequenceParameterSet const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( chroma_format_idc == rhs.chroma_format_idc ) && ( pic_width_in_luma_samples == rhs.pic_width_in_luma_samples ) && + ( pic_height_in_luma_samples == rhs.pic_height_in_luma_samples ) && ( sps_video_parameter_set_id == rhs.sps_video_parameter_set_id ) && + ( sps_max_sub_layers_minus1 == rhs.sps_max_sub_layers_minus1 ) && ( sps_seq_parameter_set_id == rhs.sps_seq_parameter_set_id ) && + ( bit_depth_luma_minus8 == rhs.bit_depth_luma_minus8 ) && ( bit_depth_chroma_minus8 == rhs.bit_depth_chroma_minus8 ) && + ( log2_max_pic_order_cnt_lsb_minus4 == rhs.log2_max_pic_order_cnt_lsb_minus4 ) && + ( log2_min_luma_coding_block_size_minus3 == rhs.log2_min_luma_coding_block_size_minus3 ) && + ( log2_diff_max_min_luma_coding_block_size == rhs.log2_diff_max_min_luma_coding_block_size ) && + ( log2_min_luma_transform_block_size_minus2 == rhs.log2_min_luma_transform_block_size_minus2 ) && + ( log2_diff_max_min_luma_transform_block_size == rhs.log2_diff_max_min_luma_transform_block_size ) && + ( max_transform_hierarchy_depth_inter == rhs.max_transform_hierarchy_depth_inter ) && + ( max_transform_hierarchy_depth_intra == rhs.max_transform_hierarchy_depth_intra ) && + ( num_short_term_ref_pic_sets == rhs.num_short_term_ref_pic_sets ) && ( num_long_term_ref_pics_sps == rhs.num_long_term_ref_pics_sps ) && + ( pcm_sample_bit_depth_luma_minus1 == rhs.pcm_sample_bit_depth_luma_minus1 ) && + ( pcm_sample_bit_depth_chroma_minus1 == rhs.pcm_sample_bit_depth_chroma_minus1 ) && + ( log2_min_pcm_luma_coding_block_size_minus3 == rhs.log2_min_pcm_luma_coding_block_size_minus3 ) && + ( log2_diff_max_min_pcm_luma_coding_block_size == rhs.log2_diff_max_min_pcm_luma_coding_block_size ) && ( reserved1 == rhs.reserved1 ) && + ( reserved2 == rhs.reserved2 ) && ( palette_max_size == rhs.palette_max_size ) && + ( delta_palette_max_predictor_size == rhs.delta_palette_max_predictor_size ) && + ( motion_vector_resolution_control_idc == rhs.motion_vector_resolution_control_idc ) && + ( sps_num_palette_predictor_initializers_minus1 == rhs.sps_num_palette_predictor_initializers_minus1 ) && + ( conf_win_left_offset == rhs.conf_win_left_offset ) && ( conf_win_right_offset == rhs.conf_win_right_offset ) && + ( conf_win_top_offset == rhs.conf_win_top_offset ) && ( conf_win_bottom_offset == rhs.conf_win_bottom_offset ) && + ( pProfileTierLevel == rhs.pProfileTierLevel ) && ( pDecPicBufMgr == rhs.pDecPicBufMgr ) && ( pScalingLists == rhs.pScalingLists ) && + ( pShortTermRefPicSet == rhs.pShortTermRefPicSet ) && ( pLongTermRefPicsSps == rhs.pLongTermRefPicsSps ) && + ( pSequenceParameterSetVui == rhs.pSequenceParameterSetVui ) && ( pPredictorPaletteEntries == rhs.pPredictorPaletteEntries ); + } + + bool operator!=( H265SequenceParameterSet const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265SpsFlags flags = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265ChromaFormatIdc chroma_format_idc = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265ChromaFormatIdc::eMonochrome; + uint32_t pic_width_in_luma_samples = {}; + uint32_t pic_height_in_luma_samples = {}; + uint8_t sps_video_parameter_set_id = {}; + uint8_t sps_max_sub_layers_minus1 = {}; + uint8_t sps_seq_parameter_set_id = {}; + uint8_t bit_depth_luma_minus8 = {}; + uint8_t bit_depth_chroma_minus8 = {}; + uint8_t log2_max_pic_order_cnt_lsb_minus4 = {}; + uint8_t log2_min_luma_coding_block_size_minus3 = {}; + uint8_t log2_diff_max_min_luma_coding_block_size = {}; + uint8_t log2_min_luma_transform_block_size_minus2 = {}; + uint8_t log2_diff_max_min_luma_transform_block_size = {}; + uint8_t max_transform_hierarchy_depth_inter = {}; + uint8_t max_transform_hierarchy_depth_intra = {}; + uint8_t num_short_term_ref_pic_sets = {}; + uint8_t num_long_term_ref_pics_sps = {}; + uint8_t pcm_sample_bit_depth_luma_minus1 = {}; + uint8_t pcm_sample_bit_depth_chroma_minus1 = {}; + uint8_t log2_min_pcm_luma_coding_block_size_minus3 = {}; + uint8_t log2_diff_max_min_pcm_luma_coding_block_size = {}; + uint8_t reserved1 = {}; + uint8_t reserved2 = {}; + uint8_t palette_max_size = {}; + uint8_t delta_palette_max_predictor_size = {}; + uint8_t motion_vector_resolution_control_idc = {}; + uint8_t sps_num_palette_predictor_initializers_minus1 = {}; + uint32_t conf_win_left_offset = {}; + uint32_t conf_win_right_offset = {}; + uint32_t conf_win_top_offset = {}; + uint32_t conf_win_bottom_offset = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265ProfileTierLevel * pProfileTierLevel = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265DecPicBufMgr * pDecPicBufMgr = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265ScalingLists * pScalingLists = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265ShortTermRefPicSet * pShortTermRefPicSet = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265LongTermRefPicsSps * pLongTermRefPicsSps = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265SequenceParameterSetVui * pSequenceParameterSetVui = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265PredictorPaletteEntries * pPredictorPaletteEntries = {}; + }; + + struct H265PpsFlags + { + using NativeType = StdVideoH265PpsFlags; + + operator StdVideoH265PpsFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265PpsFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265PpsFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( dependent_slice_segments_enabled_flag == rhs.dependent_slice_segments_enabled_flag ) && + ( output_flag_present_flag == rhs.output_flag_present_flag ) && ( sign_data_hiding_enabled_flag == rhs.sign_data_hiding_enabled_flag ) && + ( cabac_init_present_flag == rhs.cabac_init_present_flag ) && ( constrained_intra_pred_flag == rhs.constrained_intra_pred_flag ) && + ( transform_skip_enabled_flag == rhs.transform_skip_enabled_flag ) && ( cu_qp_delta_enabled_flag == rhs.cu_qp_delta_enabled_flag ) && + ( pps_slice_chroma_qp_offsets_present_flag == rhs.pps_slice_chroma_qp_offsets_present_flag ) && + ( weighted_pred_flag == rhs.weighted_pred_flag ) && ( weighted_bipred_flag == rhs.weighted_bipred_flag ) && + ( transquant_bypass_enabled_flag == rhs.transquant_bypass_enabled_flag ) && ( tiles_enabled_flag == rhs.tiles_enabled_flag ) && + ( entropy_coding_sync_enabled_flag == rhs.entropy_coding_sync_enabled_flag ) && ( uniform_spacing_flag == rhs.uniform_spacing_flag ) && + ( loop_filter_across_tiles_enabled_flag == rhs.loop_filter_across_tiles_enabled_flag ) && + ( pps_loop_filter_across_slices_enabled_flag == rhs.pps_loop_filter_across_slices_enabled_flag ) && + ( deblocking_filter_control_present_flag == rhs.deblocking_filter_control_present_flag ) && + ( deblocking_filter_override_enabled_flag == rhs.deblocking_filter_override_enabled_flag ) && + ( pps_deblocking_filter_disabled_flag == rhs.pps_deblocking_filter_disabled_flag ) && + ( pps_scaling_list_data_present_flag == rhs.pps_scaling_list_data_present_flag ) && + ( lists_modification_present_flag == rhs.lists_modification_present_flag ) && + ( slice_segment_header_extension_present_flag == rhs.slice_segment_header_extension_present_flag ) && + ( pps_extension_present_flag == rhs.pps_extension_present_flag ) && + ( cross_component_prediction_enabled_flag == rhs.cross_component_prediction_enabled_flag ) && + ( chroma_qp_offset_list_enabled_flag == rhs.chroma_qp_offset_list_enabled_flag ) && + ( pps_curr_pic_ref_enabled_flag == rhs.pps_curr_pic_ref_enabled_flag ) && + ( residual_adaptive_colour_transform_enabled_flag == rhs.residual_adaptive_colour_transform_enabled_flag ) && + ( pps_slice_act_qp_offsets_present_flag == rhs.pps_slice_act_qp_offsets_present_flag ) && + ( pps_palette_predictor_initializers_present_flag == rhs.pps_palette_predictor_initializers_present_flag ) && + ( monochrome_palette_flag == rhs.monochrome_palette_flag ) && ( pps_range_extension_flag == rhs.pps_range_extension_flag ); + } + + bool operator!=( H265PpsFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t dependent_slice_segments_enabled_flag : 1; + uint32_t output_flag_present_flag : 1; + uint32_t sign_data_hiding_enabled_flag : 1; + uint32_t cabac_init_present_flag : 1; + uint32_t constrained_intra_pred_flag : 1; + uint32_t transform_skip_enabled_flag : 1; + uint32_t cu_qp_delta_enabled_flag : 1; + uint32_t pps_slice_chroma_qp_offsets_present_flag : 1; + uint32_t weighted_pred_flag : 1; + uint32_t weighted_bipred_flag : 1; + uint32_t transquant_bypass_enabled_flag : 1; + uint32_t tiles_enabled_flag : 1; + uint32_t entropy_coding_sync_enabled_flag : 1; + uint32_t uniform_spacing_flag : 1; + uint32_t loop_filter_across_tiles_enabled_flag : 1; + uint32_t pps_loop_filter_across_slices_enabled_flag : 1; + uint32_t deblocking_filter_control_present_flag : 1; + uint32_t deblocking_filter_override_enabled_flag : 1; + uint32_t pps_deblocking_filter_disabled_flag : 1; + uint32_t pps_scaling_list_data_present_flag : 1; + uint32_t lists_modification_present_flag : 1; + uint32_t slice_segment_header_extension_present_flag : 1; + uint32_t pps_extension_present_flag : 1; + uint32_t cross_component_prediction_enabled_flag : 1; + uint32_t chroma_qp_offset_list_enabled_flag : 1; + uint32_t pps_curr_pic_ref_enabled_flag : 1; + uint32_t residual_adaptive_colour_transform_enabled_flag : 1; + uint32_t pps_slice_act_qp_offsets_present_flag : 1; + uint32_t pps_palette_predictor_initializers_present_flag : 1; + uint32_t monochrome_palette_flag : 1; + uint32_t pps_range_extension_flag : 1; + }; + + struct H265PictureParameterSet + { + using NativeType = StdVideoH265PictureParameterSet; + + operator StdVideoH265PictureParameterSet const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoH265PictureParameterSet &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( H265PictureParameterSet const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( pps_pic_parameter_set_id == rhs.pps_pic_parameter_set_id ) && + ( pps_seq_parameter_set_id == rhs.pps_seq_parameter_set_id ) && ( sps_video_parameter_set_id == rhs.sps_video_parameter_set_id ) && + ( num_extra_slice_header_bits == rhs.num_extra_slice_header_bits ) && + ( num_ref_idx_l0_default_active_minus1 == rhs.num_ref_idx_l0_default_active_minus1 ) && + ( num_ref_idx_l1_default_active_minus1 == rhs.num_ref_idx_l1_default_active_minus1 ) && ( init_qp_minus26 == rhs.init_qp_minus26 ) && + ( diff_cu_qp_delta_depth == rhs.diff_cu_qp_delta_depth ) && ( pps_cb_qp_offset == rhs.pps_cb_qp_offset ) && + ( pps_cr_qp_offset == rhs.pps_cr_qp_offset ) && ( pps_beta_offset_div2 == rhs.pps_beta_offset_div2 ) && + ( pps_tc_offset_div2 == rhs.pps_tc_offset_div2 ) && ( log2_parallel_merge_level_minus2 == rhs.log2_parallel_merge_level_minus2 ) && + ( log2_max_transform_skip_block_size_minus2 == rhs.log2_max_transform_skip_block_size_minus2 ) && + ( diff_cu_chroma_qp_offset_depth == rhs.diff_cu_chroma_qp_offset_depth ) && + ( chroma_qp_offset_list_len_minus1 == rhs.chroma_qp_offset_list_len_minus1 ) && ( cb_qp_offset_list == rhs.cb_qp_offset_list ) && + ( cr_qp_offset_list == rhs.cr_qp_offset_list ) && ( log2_sao_offset_scale_luma == rhs.log2_sao_offset_scale_luma ) && + ( log2_sao_offset_scale_chroma == rhs.log2_sao_offset_scale_chroma ) && ( pps_act_y_qp_offset_plus5 == rhs.pps_act_y_qp_offset_plus5 ) && + ( pps_act_cb_qp_offset_plus5 == rhs.pps_act_cb_qp_offset_plus5 ) && ( pps_act_cr_qp_offset_plus3 == rhs.pps_act_cr_qp_offset_plus3 ) && + ( pps_num_palette_predictor_initializers == rhs.pps_num_palette_predictor_initializers ) && + ( luma_bit_depth_entry_minus8 == rhs.luma_bit_depth_entry_minus8 ) && ( chroma_bit_depth_entry_minus8 == rhs.chroma_bit_depth_entry_minus8 ) && + ( num_tile_columns_minus1 == rhs.num_tile_columns_minus1 ) && ( num_tile_rows_minus1 == rhs.num_tile_rows_minus1 ) && + ( reserved1 == rhs.reserved1 ) && ( reserved2 == rhs.reserved2 ) && ( column_width_minus1 == rhs.column_width_minus1 ) && + ( row_height_minus1 == rhs.row_height_minus1 ) && ( reserved3 == rhs.reserved3 ) && ( pScalingLists == rhs.pScalingLists ) && + ( pPredictorPaletteEntries == rhs.pPredictorPaletteEntries ); + } + + bool operator!=( H265PictureParameterSet const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265PpsFlags flags = {}; + uint8_t pps_pic_parameter_set_id = {}; + uint8_t pps_seq_parameter_set_id = {}; + uint8_t sps_video_parameter_set_id = {}; + uint8_t num_extra_slice_header_bits = {}; + uint8_t num_ref_idx_l0_default_active_minus1 = {}; + uint8_t num_ref_idx_l1_default_active_minus1 = {}; + int8_t init_qp_minus26 = {}; + uint8_t diff_cu_qp_delta_depth = {}; + int8_t pps_cb_qp_offset = {}; + int8_t pps_cr_qp_offset = {}; + int8_t pps_beta_offset_div2 = {}; + int8_t pps_tc_offset_div2 = {}; + uint8_t log2_parallel_merge_level_minus2 = {}; + uint8_t log2_max_transform_skip_block_size_minus2 = {}; + uint8_t diff_cu_chroma_qp_offset_depth = {}; + uint8_t chroma_qp_offset_list_len_minus1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D cb_qp_offset_list = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D cr_qp_offset_list = {}; + uint8_t log2_sao_offset_scale_luma = {}; + uint8_t log2_sao_offset_scale_chroma = {}; + int8_t pps_act_y_qp_offset_plus5 = {}; + int8_t pps_act_cb_qp_offset_plus5 = {}; + int8_t pps_act_cr_qp_offset_plus3 = {}; + uint8_t pps_num_palette_predictor_initializers = {}; + uint8_t luma_bit_depth_entry_minus8 = {}; + uint8_t chroma_bit_depth_entry_minus8 = {}; + uint8_t num_tile_columns_minus1 = {}; + uint8_t num_tile_rows_minus1 = {}; + uint8_t reserved1 = {}; + uint8_t reserved2 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D column_width_minus1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D row_height_minus1 = {}; + uint32_t reserved3 = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265ScalingLists * pScalingLists = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265PredictorPaletteEntries * pPredictorPaletteEntries = {}; + }; + + //=== vulkan_video_codec_h265std_decode === + + struct DecodeH265PictureInfoFlags + { + using NativeType = StdVideoDecodeH265PictureInfoFlags; + + operator StdVideoDecodeH265PictureInfoFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoDecodeH265PictureInfoFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( DecodeH265PictureInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( IrapPicFlag == rhs.IrapPicFlag ) && ( IdrPicFlag == rhs.IdrPicFlag ) && ( IsReference == rhs.IsReference ) && + ( short_term_ref_pic_set_sps_flag == rhs.short_term_ref_pic_set_sps_flag ); + } + + bool operator!=( DecodeH265PictureInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t IrapPicFlag : 1; + uint32_t IdrPicFlag : 1; + uint32_t IsReference : 1; + uint32_t short_term_ref_pic_set_sps_flag : 1; + }; + + struct DecodeH265PictureInfo + { + using NativeType = StdVideoDecodeH265PictureInfo; + + operator StdVideoDecodeH265PictureInfo const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoDecodeH265PictureInfo &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( DecodeH265PictureInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( sps_video_parameter_set_id == rhs.sps_video_parameter_set_id ) && + ( pps_seq_parameter_set_id == rhs.pps_seq_parameter_set_id ) && ( pps_pic_parameter_set_id == rhs.pps_pic_parameter_set_id ) && + ( NumDeltaPocsOfRefRpsIdx == rhs.NumDeltaPocsOfRefRpsIdx ) && ( PicOrderCntVal == rhs.PicOrderCntVal ) && + ( NumBitsForSTRefPicSetInSlice == rhs.NumBitsForSTRefPicSetInSlice ) && ( reserved == rhs.reserved ) && + ( RefPicSetStCurrBefore == rhs.RefPicSetStCurrBefore ) && ( RefPicSetStCurrAfter == rhs.RefPicSetStCurrAfter ) && + ( RefPicSetLtCurr == rhs.RefPicSetLtCurr ); + } + + bool operator!=( DecodeH265PictureInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::DecodeH265PictureInfoFlags flags = {}; + uint8_t sps_video_parameter_set_id = {}; + uint8_t pps_seq_parameter_set_id = {}; + uint8_t pps_pic_parameter_set_id = {}; + uint8_t NumDeltaPocsOfRefRpsIdx = {}; + int32_t PicOrderCntVal = {}; + uint16_t NumBitsForSTRefPicSetInSlice = {}; + uint16_t reserved = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D RefPicSetStCurrBefore = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D RefPicSetStCurrAfter = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D RefPicSetLtCurr = {}; + }; + + struct DecodeH265ReferenceInfoFlags + { + using NativeType = StdVideoDecodeH265ReferenceInfoFlags; + + operator StdVideoDecodeH265ReferenceInfoFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoDecodeH265ReferenceInfoFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( DecodeH265ReferenceInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( used_for_long_term_reference == rhs.used_for_long_term_reference ) && ( unused_for_reference == rhs.unused_for_reference ); + } + + bool operator!=( DecodeH265ReferenceInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t used_for_long_term_reference : 1; + uint32_t unused_for_reference : 1; + }; + + struct DecodeH265ReferenceInfo + { + using NativeType = StdVideoDecodeH265ReferenceInfo; + + operator StdVideoDecodeH265ReferenceInfo const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoDecodeH265ReferenceInfo &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( DecodeH265ReferenceInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( PicOrderCntVal == rhs.PicOrderCntVal ); + } + + bool operator!=( DecodeH265ReferenceInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::DecodeH265ReferenceInfoFlags flags = {}; + int32_t PicOrderCntVal = {}; + }; + + //=== vulkan_video_codec_h265std_encode === + + struct EncodeH265WeightTableFlags + { + using NativeType = StdVideoEncodeH265WeightTableFlags; + + operator StdVideoEncodeH265WeightTableFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH265WeightTableFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH265WeightTableFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( luma_weight_l0_flag == rhs.luma_weight_l0_flag ) && ( chroma_weight_l0_flag == rhs.chroma_weight_l0_flag ) && + ( luma_weight_l1_flag == rhs.luma_weight_l1_flag ) && ( chroma_weight_l1_flag == rhs.chroma_weight_l1_flag ); + } + + bool operator!=( EncodeH265WeightTableFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint16_t luma_weight_l0_flag = {}; + uint16_t chroma_weight_l0_flag = {}; + uint16_t luma_weight_l1_flag = {}; + uint16_t chroma_weight_l1_flag = {}; + }; + + struct EncodeH265WeightTable + { + using NativeType = StdVideoEncodeH265WeightTable; + + operator StdVideoEncodeH265WeightTable const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH265WeightTable &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH265WeightTable const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( luma_log2_weight_denom == rhs.luma_log2_weight_denom ) && + ( delta_chroma_log2_weight_denom == rhs.delta_chroma_log2_weight_denom ) && ( delta_luma_weight_l0 == rhs.delta_luma_weight_l0 ) && + ( luma_offset_l0 == rhs.luma_offset_l0 ) && ( delta_chroma_weight_l0 == rhs.delta_chroma_weight_l0 ) && + ( delta_chroma_offset_l0 == rhs.delta_chroma_offset_l0 ) && ( delta_luma_weight_l1 == rhs.delta_luma_weight_l1 ) && + ( luma_offset_l1 == rhs.luma_offset_l1 ) && ( delta_chroma_weight_l1 == rhs.delta_chroma_weight_l1 ) && + ( delta_chroma_offset_l1 == rhs.delta_chroma_offset_l1 ); + } + + bool operator!=( EncodeH265WeightTable const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH265WeightTableFlags flags = {}; + uint8_t luma_log2_weight_denom = {}; + int8_t delta_chroma_log2_weight_denom = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D delta_luma_weight_l0 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D luma_offset_l0 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper2D delta_chroma_weight_l0 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper2D delta_chroma_offset_l0 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D delta_luma_weight_l1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D luma_offset_l1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper2D delta_chroma_weight_l1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper2D delta_chroma_offset_l1 = {}; + }; + + struct EncodeH265SliceSegmentHeaderFlags + { + using NativeType = StdVideoEncodeH265SliceSegmentHeaderFlags; + + operator StdVideoEncodeH265SliceSegmentHeaderFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH265SliceSegmentHeaderFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH265SliceSegmentHeaderFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( first_slice_segment_in_pic_flag == rhs.first_slice_segment_in_pic_flag ) && + ( dependent_slice_segment_flag == rhs.dependent_slice_segment_flag ) && ( slice_sao_luma_flag == rhs.slice_sao_luma_flag ) && + ( slice_sao_chroma_flag == rhs.slice_sao_chroma_flag ) && ( num_ref_idx_active_override_flag == rhs.num_ref_idx_active_override_flag ) && + ( mvd_l1_zero_flag == rhs.mvd_l1_zero_flag ) && ( cabac_init_flag == rhs.cabac_init_flag ) && + ( cu_chroma_qp_offset_enabled_flag == rhs.cu_chroma_qp_offset_enabled_flag ) && + ( deblocking_filter_override_flag == rhs.deblocking_filter_override_flag ) && + ( slice_deblocking_filter_disabled_flag == rhs.slice_deblocking_filter_disabled_flag ) && + ( collocated_from_l0_flag == rhs.collocated_from_l0_flag ) && + ( slice_loop_filter_across_slices_enabled_flag == rhs.slice_loop_filter_across_slices_enabled_flag ) && ( reserved == rhs.reserved ); + } + + bool operator!=( EncodeH265SliceSegmentHeaderFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t first_slice_segment_in_pic_flag : 1; + uint32_t dependent_slice_segment_flag : 1; + uint32_t slice_sao_luma_flag : 1; + uint32_t slice_sao_chroma_flag : 1; + uint32_t num_ref_idx_active_override_flag : 1; + uint32_t mvd_l1_zero_flag : 1; + uint32_t cabac_init_flag : 1; + uint32_t cu_chroma_qp_offset_enabled_flag : 1; + uint32_t deblocking_filter_override_flag : 1; + uint32_t slice_deblocking_filter_disabled_flag : 1; + uint32_t collocated_from_l0_flag : 1; + uint32_t slice_loop_filter_across_slices_enabled_flag : 1; + uint32_t reserved : 20; + }; + + struct EncodeH265SliceSegmentHeader + { + using NativeType = StdVideoEncodeH265SliceSegmentHeader; + + operator StdVideoEncodeH265SliceSegmentHeader const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH265SliceSegmentHeader &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH265SliceSegmentHeader const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( slice_type == rhs.slice_type ) && ( slice_segment_address == rhs.slice_segment_address ) && + ( collocated_ref_idx == rhs.collocated_ref_idx ) && ( MaxNumMergeCand == rhs.MaxNumMergeCand ) && + ( slice_cb_qp_offset == rhs.slice_cb_qp_offset ) && ( slice_cr_qp_offset == rhs.slice_cr_qp_offset ) && + ( slice_beta_offset_div2 == rhs.slice_beta_offset_div2 ) && ( slice_tc_offset_div2 == rhs.slice_tc_offset_div2 ) && + ( slice_act_y_qp_offset == rhs.slice_act_y_qp_offset ) && ( slice_act_cb_qp_offset == rhs.slice_act_cb_qp_offset ) && + ( slice_act_cr_qp_offset == rhs.slice_act_cr_qp_offset ) && ( slice_qp_delta == rhs.slice_qp_delta ) && ( reserved1 == rhs.reserved1 ) && + ( pWeightTable == rhs.pWeightTable ); + } + + bool operator!=( EncodeH265SliceSegmentHeader const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH265SliceSegmentHeaderFlags flags = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265SliceType slice_type = VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265SliceType::eB; + uint32_t slice_segment_address = {}; + uint8_t collocated_ref_idx = {}; + uint8_t MaxNumMergeCand = {}; + int8_t slice_cb_qp_offset = {}; + int8_t slice_cr_qp_offset = {}; + int8_t slice_beta_offset_div2 = {}; + int8_t slice_tc_offset_div2 = {}; + int8_t slice_act_y_qp_offset = {}; + int8_t slice_act_cb_qp_offset = {}; + int8_t slice_act_cr_qp_offset = {}; + int8_t slice_qp_delta = {}; + uint16_t reserved1 = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH265WeightTable * pWeightTable = {}; + }; + + struct EncodeH265ReferenceListsInfoFlags + { + using NativeType = StdVideoEncodeH265ReferenceListsInfoFlags; + + operator StdVideoEncodeH265ReferenceListsInfoFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH265ReferenceListsInfoFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH265ReferenceListsInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( ref_pic_list_modification_flag_l0 == rhs.ref_pic_list_modification_flag_l0 ) && + ( ref_pic_list_modification_flag_l1 == rhs.ref_pic_list_modification_flag_l1 ) && ( reserved == rhs.reserved ); + } + + bool operator!=( EncodeH265ReferenceListsInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t ref_pic_list_modification_flag_l0 : 1; + uint32_t ref_pic_list_modification_flag_l1 : 1; + uint32_t reserved : 30; + }; + + struct EncodeH265ReferenceListsInfo + { + using NativeType = StdVideoEncodeH265ReferenceListsInfo; + + operator StdVideoEncodeH265ReferenceListsInfo const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH265ReferenceListsInfo &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH265ReferenceListsInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( num_ref_idx_l0_active_minus1 == rhs.num_ref_idx_l0_active_minus1 ) && + ( num_ref_idx_l1_active_minus1 == rhs.num_ref_idx_l1_active_minus1 ) && ( RefPicList0 == rhs.RefPicList0 ) && + ( RefPicList1 == rhs.RefPicList1 ) && ( list_entry_l0 == rhs.list_entry_l0 ) && ( list_entry_l1 == rhs.list_entry_l1 ); + } + + bool operator!=( EncodeH265ReferenceListsInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH265ReferenceListsInfoFlags flags = {}; + uint8_t num_ref_idx_l0_active_minus1 = {}; + uint8_t num_ref_idx_l1_active_minus1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D RefPicList0 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D RefPicList1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D list_entry_l0 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D list_entry_l1 = {}; + }; + + struct EncodeH265PictureInfoFlags + { + using NativeType = StdVideoEncodeH265PictureInfoFlags; + + operator StdVideoEncodeH265PictureInfoFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH265PictureInfoFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH265PictureInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( is_reference == rhs.is_reference ) && ( IrapPicFlag == rhs.IrapPicFlag ) && + ( used_for_long_term_reference == rhs.used_for_long_term_reference ) && ( discardable_flag == rhs.discardable_flag ) && + ( cross_layer_bla_flag == rhs.cross_layer_bla_flag ) && ( pic_output_flag == rhs.pic_output_flag ) && + ( no_output_of_prior_pics_flag == rhs.no_output_of_prior_pics_flag ) && + ( short_term_ref_pic_set_sps_flag == rhs.short_term_ref_pic_set_sps_flag ) && + ( slice_temporal_mvp_enabled_flag == rhs.slice_temporal_mvp_enabled_flag ) && ( reserved == rhs.reserved ); + } + + bool operator!=( EncodeH265PictureInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t is_reference : 1; + uint32_t IrapPicFlag : 1; + uint32_t used_for_long_term_reference : 1; + uint32_t discardable_flag : 1; + uint32_t cross_layer_bla_flag : 1; + uint32_t pic_output_flag : 1; + uint32_t no_output_of_prior_pics_flag : 1; + uint32_t short_term_ref_pic_set_sps_flag : 1; + uint32_t slice_temporal_mvp_enabled_flag : 1; + uint32_t reserved : 23; + }; + + struct EncodeH265LongTermRefPics + { + using NativeType = StdVideoEncodeH265LongTermRefPics; + + operator StdVideoEncodeH265LongTermRefPics const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH265LongTermRefPics &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH265LongTermRefPics const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( num_long_term_sps == rhs.num_long_term_sps ) && ( num_long_term_pics == rhs.num_long_term_pics ) && ( lt_idx_sps == rhs.lt_idx_sps ) && + ( poc_lsb_lt == rhs.poc_lsb_lt ) && ( used_by_curr_pic_lt_flag == rhs.used_by_curr_pic_lt_flag ) && + ( delta_poc_msb_present_flag == rhs.delta_poc_msb_present_flag ) && ( delta_poc_msb_cycle_lt == rhs.delta_poc_msb_cycle_lt ); + } + + bool operator!=( EncodeH265LongTermRefPics const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint8_t num_long_term_sps = {}; + uint8_t num_long_term_pics = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D lt_idx_sps = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D poc_lsb_lt = {}; + uint16_t used_by_curr_pic_lt_flag = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D delta_poc_msb_present_flag = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D delta_poc_msb_cycle_lt = {}; + }; + + struct EncodeH265PictureInfo + { + using NativeType = StdVideoEncodeH265PictureInfo; + + operator StdVideoEncodeH265PictureInfo const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH265PictureInfo &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH265PictureInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( pic_type == rhs.pic_type ) && ( sps_video_parameter_set_id == rhs.sps_video_parameter_set_id ) && + ( pps_seq_parameter_set_id == rhs.pps_seq_parameter_set_id ) && ( pps_pic_parameter_set_id == rhs.pps_pic_parameter_set_id ) && + ( short_term_ref_pic_set_idx == rhs.short_term_ref_pic_set_idx ) && ( PicOrderCntVal == rhs.PicOrderCntVal ) && + ( TemporalId == rhs.TemporalId ) && ( reserved1 == rhs.reserved1 ) && ( pRefLists == rhs.pRefLists ) && + ( pShortTermRefPicSet == rhs.pShortTermRefPicSet ) && ( pLongTermRefPics == rhs.pLongTermRefPics ); + } + + bool operator!=( EncodeH265PictureInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH265PictureInfoFlags flags = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265PictureType pic_type = VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265PictureType::eP; + uint8_t sps_video_parameter_set_id = {}; + uint8_t pps_seq_parameter_set_id = {}; + uint8_t pps_pic_parameter_set_id = {}; + uint8_t short_term_ref_pic_set_idx = {}; + int32_t PicOrderCntVal = {}; + uint8_t TemporalId = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D reserved1 = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH265ReferenceListsInfo * pRefLists = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265ShortTermRefPicSet * pShortTermRefPicSet = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH265LongTermRefPics * pLongTermRefPics = {}; + }; + + struct EncodeH265ReferenceInfoFlags + { + using NativeType = StdVideoEncodeH265ReferenceInfoFlags; + + operator StdVideoEncodeH265ReferenceInfoFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH265ReferenceInfoFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH265ReferenceInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( used_for_long_term_reference == rhs.used_for_long_term_reference ) && ( unused_for_reference == rhs.unused_for_reference ) && + ( reserved == rhs.reserved ); + } + + bool operator!=( EncodeH265ReferenceInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t used_for_long_term_reference : 1; + uint32_t unused_for_reference : 1; + uint32_t reserved : 30; + }; + + struct EncodeH265ReferenceInfo + { + using NativeType = StdVideoEncodeH265ReferenceInfo; + + operator StdVideoEncodeH265ReferenceInfo const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoEncodeH265ReferenceInfo &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( EncodeH265ReferenceInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( pic_type == rhs.pic_type ) && ( PicOrderCntVal == rhs.PicOrderCntVal ) && ( TemporalId == rhs.TemporalId ); + } + + bool operator!=( EncodeH265ReferenceInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::EncodeH265ReferenceInfoFlags flags = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265PictureType pic_type = VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::H265PictureType::eP; + int32_t PicOrderCntVal = {}; + uint8_t TemporalId = {}; + }; + + //=== vulkan_video_codec_av1std === + + struct AV1ColorConfigFlags + { + using NativeType = StdVideoAV1ColorConfigFlags; + + operator StdVideoAV1ColorConfigFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1ColorConfigFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1ColorConfigFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( mono_chrome == rhs.mono_chrome ) && ( color_range == rhs.color_range ) && ( separate_uv_delta_q == rhs.separate_uv_delta_q ) && + ( color_description_present_flag == rhs.color_description_present_flag ) && ( reserved == rhs.reserved ); + } + + bool operator!=( AV1ColorConfigFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t mono_chrome : 1; + uint32_t color_range : 1; + uint32_t separate_uv_delta_q : 1; + uint32_t color_description_present_flag : 1; + uint32_t reserved : 28; + }; + + struct AV1ColorConfig + { + using NativeType = StdVideoAV1ColorConfig; + + operator StdVideoAV1ColorConfig const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1ColorConfig &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1ColorConfig const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( BitDepth == rhs.BitDepth ) && ( subsampling_x == rhs.subsampling_x ) && ( subsampling_y == rhs.subsampling_y ) && + ( reserved1 == rhs.reserved1 ) && ( color_primaries == rhs.color_primaries ) && ( transfer_characteristics == rhs.transfer_characteristics ) && + ( matrix_coefficients == rhs.matrix_coefficients ) && ( chroma_sample_position == rhs.chroma_sample_position ); + } + + bool operator!=( AV1ColorConfig const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1ColorConfigFlags flags = {}; + uint8_t BitDepth = {}; + uint8_t subsampling_x = {}; + uint8_t subsampling_y = {}; + uint8_t reserved1 = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1ColorPrimaries color_primaries = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1ColorPrimaries::eBt709; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1TransferCharacteristics transfer_characteristics = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1TransferCharacteristics::eReserved0; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1MatrixCoefficients matrix_coefficients = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1MatrixCoefficients::eIdentity; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1ChromaSamplePosition chroma_sample_position = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1ChromaSamplePosition::eUnknown; + }; + + struct AV1TimingInfoFlags + { + using NativeType = StdVideoAV1TimingInfoFlags; + + operator StdVideoAV1TimingInfoFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1TimingInfoFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1TimingInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( equal_picture_interval == rhs.equal_picture_interval ) && ( reserved == rhs.reserved ); + } + + bool operator!=( AV1TimingInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t equal_picture_interval : 1; + uint32_t reserved : 31; + }; + + struct AV1TimingInfo + { + using NativeType = StdVideoAV1TimingInfo; + + operator StdVideoAV1TimingInfo const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1TimingInfo &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1TimingInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( num_units_in_display_tick == rhs.num_units_in_display_tick ) && ( time_scale == rhs.time_scale ) && + ( num_ticks_per_picture_minus_1 == rhs.num_ticks_per_picture_minus_1 ); + } + + bool operator!=( AV1TimingInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1TimingInfoFlags flags = {}; + uint32_t num_units_in_display_tick = {}; + uint32_t time_scale = {}; + uint32_t num_ticks_per_picture_minus_1 = {}; + }; + + struct AV1LoopFilterFlags + { + using NativeType = StdVideoAV1LoopFilterFlags; + + operator StdVideoAV1LoopFilterFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1LoopFilterFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1LoopFilterFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( loop_filter_delta_enabled == rhs.loop_filter_delta_enabled ) && ( loop_filter_delta_update == rhs.loop_filter_delta_update ) && + ( reserved == rhs.reserved ); + } + + bool operator!=( AV1LoopFilterFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t loop_filter_delta_enabled : 1; + uint32_t loop_filter_delta_update : 1; + uint32_t reserved : 30; + }; + + struct AV1LoopFilter + { + using NativeType = StdVideoAV1LoopFilter; + + operator StdVideoAV1LoopFilter const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1LoopFilter &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1LoopFilter const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( loop_filter_level == rhs.loop_filter_level ) && ( loop_filter_sharpness == rhs.loop_filter_sharpness ) && + ( update_ref_delta == rhs.update_ref_delta ) && ( loop_filter_ref_deltas == rhs.loop_filter_ref_deltas ) && + ( update_mode_delta == rhs.update_mode_delta ) && ( loop_filter_mode_deltas == rhs.loop_filter_mode_deltas ); + } + + bool operator!=( AV1LoopFilter const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1LoopFilterFlags flags = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D loop_filter_level = {}; + uint8_t loop_filter_sharpness = {}; + uint8_t update_ref_delta = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D loop_filter_ref_deltas = {}; + uint8_t update_mode_delta = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D loop_filter_mode_deltas = {}; + }; + + struct AV1QuantizationFlags + { + using NativeType = StdVideoAV1QuantizationFlags; + + operator StdVideoAV1QuantizationFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1QuantizationFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1QuantizationFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( using_qmatrix == rhs.using_qmatrix ) && ( diff_uv_delta == rhs.diff_uv_delta ) && ( reserved == rhs.reserved ); + } + + bool operator!=( AV1QuantizationFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t using_qmatrix : 1; + uint32_t diff_uv_delta : 1; + uint32_t reserved : 30; + }; + + struct AV1Quantization + { + using NativeType = StdVideoAV1Quantization; + + operator StdVideoAV1Quantization const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1Quantization &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1Quantization const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( base_q_idx == rhs.base_q_idx ) && ( DeltaQYDc == rhs.DeltaQYDc ) && ( DeltaQUDc == rhs.DeltaQUDc ) && + ( DeltaQUAc == rhs.DeltaQUAc ) && ( DeltaQVDc == rhs.DeltaQVDc ) && ( DeltaQVAc == rhs.DeltaQVAc ) && ( qm_y == rhs.qm_y ) && + ( qm_u == rhs.qm_u ) && ( qm_v == rhs.qm_v ); + } + + bool operator!=( AV1Quantization const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1QuantizationFlags flags = {}; + uint8_t base_q_idx = {}; + int8_t DeltaQYDc = {}; + int8_t DeltaQUDc = {}; + int8_t DeltaQUAc = {}; + int8_t DeltaQVDc = {}; + int8_t DeltaQVAc = {}; + uint8_t qm_y = {}; + uint8_t qm_u = {}; + uint8_t qm_v = {}; + }; + + struct AV1Segmentation + { + using NativeType = StdVideoAV1Segmentation; + + operator StdVideoAV1Segmentation const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1Segmentation &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1Segmentation const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( FeatureEnabled == rhs.FeatureEnabled ) && ( FeatureData == rhs.FeatureData ); + } + + bool operator!=( AV1Segmentation const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::ArrayWrapper1D FeatureEnabled = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper2D FeatureData = {}; + }; + + struct AV1TileInfoFlags + { + using NativeType = StdVideoAV1TileInfoFlags; + + operator StdVideoAV1TileInfoFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1TileInfoFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1TileInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( uniform_tile_spacing_flag == rhs.uniform_tile_spacing_flag ) && ( reserved == rhs.reserved ); + } + + bool operator!=( AV1TileInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t uniform_tile_spacing_flag : 1; + uint32_t reserved : 31; + }; + + struct AV1TileInfo + { + using NativeType = StdVideoAV1TileInfo; + + operator StdVideoAV1TileInfo const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1TileInfo &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1TileInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( TileCols == rhs.TileCols ) && ( TileRows == rhs.TileRows ) && + ( context_update_tile_id == rhs.context_update_tile_id ) && ( tile_size_bytes_minus_1 == rhs.tile_size_bytes_minus_1 ) && + ( reserved1 == rhs.reserved1 ) && ( pMiColStarts == rhs.pMiColStarts ) && ( pMiRowStarts == rhs.pMiRowStarts ) && + ( pWidthInSbsMinus1 == rhs.pWidthInSbsMinus1 ) && ( pHeightInSbsMinus1 == rhs.pHeightInSbsMinus1 ); + } + + bool operator!=( AV1TileInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1TileInfoFlags flags = {}; + uint8_t TileCols = {}; + uint8_t TileRows = {}; + uint16_t context_update_tile_id = {}; + uint8_t tile_size_bytes_minus_1 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D reserved1 = {}; + const uint16_t * pMiColStarts = {}; + const uint16_t * pMiRowStarts = {}; + const uint16_t * pWidthInSbsMinus1 = {}; + const uint16_t * pHeightInSbsMinus1 = {}; + }; + + struct AV1CDEF + { + using NativeType = StdVideoAV1CDEF; + + operator StdVideoAV1CDEF const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1CDEF &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1CDEF const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( cdef_damping_minus_3 == rhs.cdef_damping_minus_3 ) && ( cdef_bits == rhs.cdef_bits ) && ( cdef_y_pri_strength == rhs.cdef_y_pri_strength ) && + ( cdef_y_sec_strength == rhs.cdef_y_sec_strength ) && ( cdef_uv_pri_strength == rhs.cdef_uv_pri_strength ) && + ( cdef_uv_sec_strength == rhs.cdef_uv_sec_strength ); + } + + bool operator!=( AV1CDEF const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint8_t cdef_damping_minus_3 = {}; + uint8_t cdef_bits = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D cdef_y_pri_strength = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D cdef_y_sec_strength = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D cdef_uv_pri_strength = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D cdef_uv_sec_strength = {}; + }; + + struct AV1LoopRestoration + { + using NativeType = StdVideoAV1LoopRestoration; + + operator StdVideoAV1LoopRestoration const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1LoopRestoration &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1LoopRestoration const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( FrameRestorationType == rhs.FrameRestorationType ) && ( LoopRestorationSize == rhs.LoopRestorationSize ); + } + + bool operator!=( AV1LoopRestoration const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::ArrayWrapper1D FrameRestorationType = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D LoopRestorationSize = {}; + }; + + struct AV1GlobalMotion + { + using NativeType = StdVideoAV1GlobalMotion; + + operator StdVideoAV1GlobalMotion const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1GlobalMotion &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1GlobalMotion const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( GmType == rhs.GmType ) && ( gm_params == rhs.gm_params ); + } + + bool operator!=( AV1GlobalMotion const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::ArrayWrapper1D GmType = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper2D gm_params = {}; + }; + + struct AV1FilmGrainFlags + { + using NativeType = StdVideoAV1FilmGrainFlags; + + operator StdVideoAV1FilmGrainFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1FilmGrainFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1FilmGrainFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( chroma_scaling_from_luma == rhs.chroma_scaling_from_luma ) && ( overlap_flag == rhs.overlap_flag ) && + ( clip_to_restricted_range == rhs.clip_to_restricted_range ) && ( update_grain == rhs.update_grain ) && ( reserved == rhs.reserved ); + } + + bool operator!=( AV1FilmGrainFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t chroma_scaling_from_luma : 1; + uint32_t overlap_flag : 1; + uint32_t clip_to_restricted_range : 1; + uint32_t update_grain : 1; + uint32_t reserved : 28; + }; + + struct AV1FilmGrain + { + using NativeType = StdVideoAV1FilmGrain; + + operator StdVideoAV1FilmGrain const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1FilmGrain &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1FilmGrain const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( grain_scaling_minus_8 == rhs.grain_scaling_minus_8 ) && ( ar_coeff_lag == rhs.ar_coeff_lag ) && + ( ar_coeff_shift_minus_6 == rhs.ar_coeff_shift_minus_6 ) && ( grain_scale_shift == rhs.grain_scale_shift ) && ( grain_seed == rhs.grain_seed ) && + ( film_grain_params_ref_idx == rhs.film_grain_params_ref_idx ) && ( num_y_points == rhs.num_y_points ) && + ( point_y_value == rhs.point_y_value ) && ( point_y_scaling == rhs.point_y_scaling ) && ( num_cb_points == rhs.num_cb_points ) && + ( point_cb_value == rhs.point_cb_value ) && ( point_cb_scaling == rhs.point_cb_scaling ) && ( num_cr_points == rhs.num_cr_points ) && + ( point_cr_value == rhs.point_cr_value ) && ( point_cr_scaling == rhs.point_cr_scaling ) && + ( ar_coeffs_y_plus_128 == rhs.ar_coeffs_y_plus_128 ) && ( ar_coeffs_cb_plus_128 == rhs.ar_coeffs_cb_plus_128 ) && + ( ar_coeffs_cr_plus_128 == rhs.ar_coeffs_cr_plus_128 ) && ( cb_mult == rhs.cb_mult ) && ( cb_luma_mult == rhs.cb_luma_mult ) && + ( cb_offset == rhs.cb_offset ) && ( cr_mult == rhs.cr_mult ) && ( cr_luma_mult == rhs.cr_luma_mult ) && ( cr_offset == rhs.cr_offset ); + } + + bool operator!=( AV1FilmGrain const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1FilmGrainFlags flags = {}; + uint8_t grain_scaling_minus_8 = {}; + uint8_t ar_coeff_lag = {}; + uint8_t ar_coeff_shift_minus_6 = {}; + uint8_t grain_scale_shift = {}; + uint16_t grain_seed = {}; + uint8_t film_grain_params_ref_idx = {}; + uint8_t num_y_points = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D point_y_value = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D point_y_scaling = {}; + uint8_t num_cb_points = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D point_cb_value = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D point_cb_scaling = {}; + uint8_t num_cr_points = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D point_cr_value = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D point_cr_scaling = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D ar_coeffs_y_plus_128 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D ar_coeffs_cb_plus_128 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D ar_coeffs_cr_plus_128 = {}; + uint8_t cb_mult = {}; + uint8_t cb_luma_mult = {}; + uint16_t cb_offset = {}; + uint8_t cr_mult = {}; + uint8_t cr_luma_mult = {}; + uint16_t cr_offset = {}; + }; + + struct AV1SequenceHeaderFlags + { + using NativeType = StdVideoAV1SequenceHeaderFlags; + + operator StdVideoAV1SequenceHeaderFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1SequenceHeaderFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1SequenceHeaderFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( still_picture == rhs.still_picture ) && ( reduced_still_picture_header == rhs.reduced_still_picture_header ) && + ( use_128x128_superblock == rhs.use_128x128_superblock ) && ( enable_filter_intra == rhs.enable_filter_intra ) && + ( enable_intra_edge_filter == rhs.enable_intra_edge_filter ) && ( enable_interintra_compound == rhs.enable_interintra_compound ) && + ( enable_masked_compound == rhs.enable_masked_compound ) && ( enable_warped_motion == rhs.enable_warped_motion ) && + ( enable_dual_filter == rhs.enable_dual_filter ) && ( enable_order_hint == rhs.enable_order_hint ) && + ( enable_jnt_comp == rhs.enable_jnt_comp ) && ( enable_ref_frame_mvs == rhs.enable_ref_frame_mvs ) && + ( frame_id_numbers_present_flag == rhs.frame_id_numbers_present_flag ) && ( enable_superres == rhs.enable_superres ) && + ( enable_cdef == rhs.enable_cdef ) && ( enable_restoration == rhs.enable_restoration ) && + ( film_grain_params_present == rhs.film_grain_params_present ) && ( timing_info_present_flag == rhs.timing_info_present_flag ) && + ( initial_display_delay_present_flag == rhs.initial_display_delay_present_flag ) && ( reserved == rhs.reserved ); + } + + bool operator!=( AV1SequenceHeaderFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t still_picture : 1; + uint32_t reduced_still_picture_header : 1; + uint32_t use_128x128_superblock : 1; + uint32_t enable_filter_intra : 1; + uint32_t enable_intra_edge_filter : 1; + uint32_t enable_interintra_compound : 1; + uint32_t enable_masked_compound : 1; + uint32_t enable_warped_motion : 1; + uint32_t enable_dual_filter : 1; + uint32_t enable_order_hint : 1; + uint32_t enable_jnt_comp : 1; + uint32_t enable_ref_frame_mvs : 1; + uint32_t frame_id_numbers_present_flag : 1; + uint32_t enable_superres : 1; + uint32_t enable_cdef : 1; + uint32_t enable_restoration : 1; + uint32_t film_grain_params_present : 1; + uint32_t timing_info_present_flag : 1; + uint32_t initial_display_delay_present_flag : 1; + uint32_t reserved : 13; + }; + + struct AV1SequenceHeader + { + using NativeType = StdVideoAV1SequenceHeader; + + operator StdVideoAV1SequenceHeader const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoAV1SequenceHeader &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( AV1SequenceHeader const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( seq_profile == rhs.seq_profile ) && ( frame_width_bits_minus_1 == rhs.frame_width_bits_minus_1 ) && + ( frame_height_bits_minus_1 == rhs.frame_height_bits_minus_1 ) && ( max_frame_width_minus_1 == rhs.max_frame_width_minus_1 ) && + ( max_frame_height_minus_1 == rhs.max_frame_height_minus_1 ) && ( delta_frame_id_length_minus_2 == rhs.delta_frame_id_length_minus_2 ) && + ( additional_frame_id_length_minus_1 == rhs.additional_frame_id_length_minus_1 ) && ( order_hint_bits_minus_1 == rhs.order_hint_bits_minus_1 ) && + ( seq_force_integer_mv == rhs.seq_force_integer_mv ) && ( seq_force_screen_content_tools == rhs.seq_force_screen_content_tools ) && + ( reserved1 == rhs.reserved1 ) && ( pColorConfig == rhs.pColorConfig ) && ( pTimingInfo == rhs.pTimingInfo ); + } + + bool operator!=( AV1SequenceHeader const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1SequenceHeaderFlags flags = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1Profile seq_profile = VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1Profile::eMain; + uint8_t frame_width_bits_minus_1 = {}; + uint8_t frame_height_bits_minus_1 = {}; + uint16_t max_frame_width_minus_1 = {}; + uint16_t max_frame_height_minus_1 = {}; + uint8_t delta_frame_id_length_minus_2 = {}; + uint8_t additional_frame_id_length_minus_1 = {}; + uint8_t order_hint_bits_minus_1 = {}; + uint8_t seq_force_integer_mv = {}; + uint8_t seq_force_screen_content_tools = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D reserved1 = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1ColorConfig * pColorConfig = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1TimingInfo * pTimingInfo = {}; + }; + + //=== vulkan_video_codec_av1std_decode === + + struct DecodeAV1PictureInfoFlags + { + using NativeType = StdVideoDecodeAV1PictureInfoFlags; + + operator StdVideoDecodeAV1PictureInfoFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoDecodeAV1PictureInfoFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( DecodeAV1PictureInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( error_resilient_mode == rhs.error_resilient_mode ) && ( disable_cdf_update == rhs.disable_cdf_update ) && + ( use_superres == rhs.use_superres ) && ( render_and_frame_size_different == rhs.render_and_frame_size_different ) && + ( allow_screen_content_tools == rhs.allow_screen_content_tools ) && ( is_filter_switchable == rhs.is_filter_switchable ) && + ( force_integer_mv == rhs.force_integer_mv ) && ( frame_size_override_flag == rhs.frame_size_override_flag ) && + ( buffer_removal_time_present_flag == rhs.buffer_removal_time_present_flag ) && ( allow_intrabc == rhs.allow_intrabc ) && + ( frame_refs_short_signaling == rhs.frame_refs_short_signaling ) && ( allow_high_precision_mv == rhs.allow_high_precision_mv ) && + ( is_motion_mode_switchable == rhs.is_motion_mode_switchable ) && ( use_ref_frame_mvs == rhs.use_ref_frame_mvs ) && + ( disable_frame_end_update_cdf == rhs.disable_frame_end_update_cdf ) && ( allow_warped_motion == rhs.allow_warped_motion ) && + ( reduced_tx_set == rhs.reduced_tx_set ) && ( reference_select == rhs.reference_select ) && ( skip_mode_present == rhs.skip_mode_present ) && + ( delta_q_present == rhs.delta_q_present ) && ( delta_lf_present == rhs.delta_lf_present ) && ( delta_lf_multi == rhs.delta_lf_multi ) && + ( segmentation_enabled == rhs.segmentation_enabled ) && ( segmentation_update_map == rhs.segmentation_update_map ) && + ( segmentation_temporal_update == rhs.segmentation_temporal_update ) && ( segmentation_update_data == rhs.segmentation_update_data ) && + ( UsesLr == rhs.UsesLr ) && ( usesChromaLr == rhs.usesChromaLr ) && ( apply_grain == rhs.apply_grain ) && ( reserved == rhs.reserved ); + } + + bool operator!=( DecodeAV1PictureInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t error_resilient_mode : 1; + uint32_t disable_cdf_update : 1; + uint32_t use_superres : 1; + uint32_t render_and_frame_size_different : 1; + uint32_t allow_screen_content_tools : 1; + uint32_t is_filter_switchable : 1; + uint32_t force_integer_mv : 1; + uint32_t frame_size_override_flag : 1; + uint32_t buffer_removal_time_present_flag : 1; + uint32_t allow_intrabc : 1; + uint32_t frame_refs_short_signaling : 1; + uint32_t allow_high_precision_mv : 1; + uint32_t is_motion_mode_switchable : 1; + uint32_t use_ref_frame_mvs : 1; + uint32_t disable_frame_end_update_cdf : 1; + uint32_t allow_warped_motion : 1; + uint32_t reduced_tx_set : 1; + uint32_t reference_select : 1; + uint32_t skip_mode_present : 1; + uint32_t delta_q_present : 1; + uint32_t delta_lf_present : 1; + uint32_t delta_lf_multi : 1; + uint32_t segmentation_enabled : 1; + uint32_t segmentation_update_map : 1; + uint32_t segmentation_temporal_update : 1; + uint32_t segmentation_update_data : 1; + uint32_t UsesLr : 1; + uint32_t usesChromaLr : 1; + uint32_t apply_grain : 1; + uint32_t reserved : 3; + }; + + struct DecodeAV1PictureInfo + { + using NativeType = StdVideoDecodeAV1PictureInfo; + + operator StdVideoDecodeAV1PictureInfo const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoDecodeAV1PictureInfo &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( DecodeAV1PictureInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( frame_type == rhs.frame_type ) && ( current_frame_id == rhs.current_frame_id ) && ( OrderHint == rhs.OrderHint ) && + ( primary_ref_frame == rhs.primary_ref_frame ) && ( refresh_frame_flags == rhs.refresh_frame_flags ) && ( reserved1 == rhs.reserved1 ) && + ( interpolation_filter == rhs.interpolation_filter ) && ( TxMode == rhs.TxMode ) && ( delta_q_res == rhs.delta_q_res ) && + ( delta_lf_res == rhs.delta_lf_res ) && ( SkipModeFrame == rhs.SkipModeFrame ) && ( coded_denom == rhs.coded_denom ) && + ( reserved2 == rhs.reserved2 ) && ( OrderHints == rhs.OrderHints ) && ( expectedFrameId == rhs.expectedFrameId ) && + ( pTileInfo == rhs.pTileInfo ) && ( pQuantization == rhs.pQuantization ) && ( pSegmentation == rhs.pSegmentation ) && + ( pLoopFilter == rhs.pLoopFilter ) && ( pCDEF == rhs.pCDEF ) && ( pLoopRestoration == rhs.pLoopRestoration ) && + ( pGlobalMotion == rhs.pGlobalMotion ) && ( pFilmGrain == rhs.pFilmGrain ); + } + + bool operator!=( DecodeAV1PictureInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::DecodeAV1PictureInfoFlags flags = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1FrameType frame_type = VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1FrameType::eKey; + uint32_t current_frame_id = {}; + uint8_t OrderHint = {}; + uint8_t primary_ref_frame = {}; + uint8_t refresh_frame_flags = {}; + uint8_t reserved1 = {}; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1InterpolationFilter interpolation_filter = + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1InterpolationFilter::eEighttap; + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1TxMode TxMode = VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1TxMode::eOnly4X4; + uint8_t delta_q_res = {}; + uint8_t delta_lf_res = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D SkipModeFrame = {}; + uint8_t coded_denom = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D reserved2 = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D OrderHints = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D expectedFrameId = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1TileInfo * pTileInfo = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1Quantization * pQuantization = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1Segmentation * pSegmentation = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1LoopFilter * pLoopFilter = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1CDEF * pCDEF = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1LoopRestoration * pLoopRestoration = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1GlobalMotion * pGlobalMotion = {}; + const VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::AV1FilmGrain * pFilmGrain = {}; + }; + + struct DecodeAV1ReferenceInfoFlags + { + using NativeType = StdVideoDecodeAV1ReferenceInfoFlags; + + operator StdVideoDecodeAV1ReferenceInfoFlags const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoDecodeAV1ReferenceInfoFlags &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( DecodeAV1ReferenceInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( disable_frame_end_update_cdf == rhs.disable_frame_end_update_cdf ) && ( segmentation_enabled == rhs.segmentation_enabled ) && + ( reserved == rhs.reserved ); + } + + bool operator!=( DecodeAV1ReferenceInfoFlags const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + uint32_t disable_frame_end_update_cdf : 1; + uint32_t segmentation_enabled : 1; + uint32_t reserved : 30; + }; + + struct DecodeAV1ReferenceInfo + { + using NativeType = StdVideoDecodeAV1ReferenceInfo; + + operator StdVideoDecodeAV1ReferenceInfo const &() const VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + operator StdVideoDecodeAV1ReferenceInfo &() VULKAN_HPP_NOEXCEPT + { + return *reinterpret_cast( this ); + } + + bool operator==( DecodeAV1ReferenceInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return ( flags == rhs.flags ) && ( frame_type == rhs.frame_type ) && ( RefFrameSignBias == rhs.RefFrameSignBias ) && ( OrderHint == rhs.OrderHint ) && + ( SavedOrderHints == rhs.SavedOrderHints ); + } + + bool operator!=( DecodeAV1ReferenceInfo const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return !operator==( rhs ); + } + + public: + VULKAN_HPP_NAMESPACE::VULKAN_HPP_VIDEO_NAMESPACE::DecodeAV1ReferenceInfoFlags flags = {}; + uint8_t frame_type = {}; + uint8_t RefFrameSignBias = {}; + uint8_t OrderHint = {}; + VULKAN_HPP_NAMESPACE::ArrayWrapper1D SavedOrderHints = {}; + }; + + } // namespace VULKAN_HPP_VIDEO_NAMESPACE +} // namespace VULKAN_HPP_NAMESPACE +#endif diff --git a/external/vulkan/vulkan_wayland.h b/external/vulkan/vulkan_wayland.h index 9afd0b7..ec706a1 100644 --- a/external/vulkan/vulkan_wayland.h +++ b/external/vulkan/vulkan_wayland.h @@ -2,7 +2,7 @@ #define VULKAN_WAYLAND_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ extern "C" { +// VK_KHR_wayland_surface is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_wayland_surface 1 #define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 6 #define VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "VK_KHR_wayland_surface" diff --git a/external/vulkan/vulkan_win32.h b/external/vulkan/vulkan_win32.h index a8e46c8..d7a0b2b 100644 --- a/external/vulkan/vulkan_win32.h +++ b/external/vulkan/vulkan_win32.h @@ -2,7 +2,7 @@ #define VULKAN_WIN32_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ extern "C" { +// VK_KHR_win32_surface is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_win32_surface 1 #define VK_KHR_WIN32_SURFACE_SPEC_VERSION 6 #define VK_KHR_WIN32_SURFACE_EXTENSION_NAME "VK_KHR_win32_surface" @@ -47,6 +48,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR( #endif +// VK_KHR_external_memory_win32 is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_external_memory_win32 1 #define VK_KHR_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1 #define VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_KHR_external_memory_win32" @@ -96,6 +98,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandlePropertiesKHR( #endif +// VK_KHR_win32_keyed_mutex is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_win32_keyed_mutex 1 #define VK_KHR_WIN32_KEYED_MUTEX_SPEC_VERSION 1 #define VK_KHR_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_KHR_win32_keyed_mutex" @@ -113,6 +116,7 @@ typedef struct VkWin32KeyedMutexAcquireReleaseInfoKHR { +// VK_KHR_external_semaphore_win32 is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_external_semaphore_win32 1 #define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_SPEC_VERSION 1 #define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME "VK_KHR_external_semaphore_win32" @@ -165,6 +169,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreWin32HandleKHR( #endif +// VK_KHR_external_fence_win32 is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_external_fence_win32 1 #define VK_KHR_EXTERNAL_FENCE_WIN32_SPEC_VERSION 1 #define VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME "VK_KHR_external_fence_win32" @@ -208,6 +213,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceWin32HandleKHR( #endif +// VK_NV_external_memory_win32 is a preprocessor guard. Do not pass it to API calls. #define VK_NV_external_memory_win32 1 #define VK_NV_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1 #define VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_NV_external_memory_win32" @@ -236,6 +242,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleNV( #endif +// VK_NV_win32_keyed_mutex is a preprocessor guard. Do not pass it to API calls. #define VK_NV_win32_keyed_mutex 1 #define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 2 #define VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_NV_win32_keyed_mutex" @@ -253,6 +260,7 @@ typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV { +// VK_EXT_full_screen_exclusive is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_full_screen_exclusive 1 #define VK_EXT_FULL_SCREEN_EXCLUSIVE_SPEC_VERSION 4 #define VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME "VK_EXT_full_screen_exclusive" @@ -309,6 +317,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModes2EXT( #endif +// VK_NV_acquire_winrt_display is a preprocessor guard. Do not pass it to API calls. #define VK_NV_acquire_winrt_display 1 #define VK_NV_ACQUIRE_WINRT_DISPLAY_SPEC_VERSION 1 #define VK_NV_ACQUIRE_WINRT_DISPLAY_EXTENSION_NAME "VK_NV_acquire_winrt_display" diff --git a/external/vulkan/vulkan_xcb.h b/external/vulkan/vulkan_xcb.h index 68e61b8..cdf6b52 100644 --- a/external/vulkan/vulkan_xcb.h +++ b/external/vulkan/vulkan_xcb.h @@ -2,7 +2,7 @@ #define VULKAN_XCB_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ extern "C" { +// VK_KHR_xcb_surface is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_xcb_surface 1 #define VK_KHR_XCB_SURFACE_SPEC_VERSION 6 #define VK_KHR_XCB_SURFACE_EXTENSION_NAME "VK_KHR_xcb_surface" diff --git a/external/vulkan/vulkan_xlib.h b/external/vulkan/vulkan_xlib.h index ea5360a..b3c3e27 100644 --- a/external/vulkan/vulkan_xlib.h +++ b/external/vulkan/vulkan_xlib.h @@ -2,7 +2,7 @@ #define VULKAN_XLIB_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ extern "C" { +// VK_KHR_xlib_surface is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_xlib_surface 1 #define VK_KHR_XLIB_SURFACE_SPEC_VERSION 6 #define VK_KHR_XLIB_SURFACE_EXTENSION_NAME "VK_KHR_xlib_surface" diff --git a/external/vulkan/vulkan_xlib_xrandr.h b/external/vulkan/vulkan_xlib_xrandr.h index 8fc35cf..8e99190 100644 --- a/external/vulkan/vulkan_xlib_xrandr.h +++ b/external/vulkan/vulkan_xlib_xrandr.h @@ -2,7 +2,7 @@ #define VULKAN_XLIB_XRANDR_H_ 1 /* -** Copyright 2015-2022 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ extern "C" { +// VK_EXT_acquire_xlib_display is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_acquire_xlib_display 1 #define VK_EXT_ACQUIRE_XLIB_DISPLAY_SPEC_VERSION 1 #define VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_xlib_display" diff --git a/src/render/render.cpp b/src/render/render.cpp index 2a2c924..12954f1 100644 --- a/src/render/render.cpp +++ b/src/render/render.cpp @@ -222,16 +222,17 @@ PlumageRender::PlumageRender() { const std::string assetpath = getAssetPath(); - if (_access(assetpath.c_str(),0) != 0) { + if (std::filesystem::exists(assetpath.c_str())) { + std::string msg = "asset path get " + assetpath; + std::cout << msg << std::endl; + } + else + { std::string msg = "Could not locate asset path in \"" + assetpath + "\".\nMake sure binary is running from correct relative directory!"; std::cerr << msg << std::endl; system("pause"); //exit(-1); } - else { - std::string msg = "asset path get " + assetpath; - std::cout << msg << std::endl; - } readDirectory(assetpath + "environments", "*.ktx", environments, false); @@ -1805,58 +1806,70 @@ PlumageRender::PlumageRender() void PlumageRender::outputImageSequence() { - + // 比较已保存的帧数和设置里的开始帧数,在生成前清理上一次生成的图片序列 if (savedFrameCounter == settings.startFrameCount) { std::cout << "clean up directory for image sequence generation" << std::endl; removeImageSequence(); } - + // 根据显卡编号设置输出路径(todo:提前到配置里) filePath.deviceSpecFilePath = filePath.imageOutputPath + "/device" + std::to_string(selectedPhysicalDeviceIndex); - + // 非第一次生成,生成结束的边界条件 if (savedFrameCounter > settings.outputFrameCount) { - if (signal.imageSequenceOutputComplete) // 避免重复改变为true + // 避免重复改变为true带来的无效性能开销 + if (signal.imageSequenceOutputComplete) { return; } + // 生成结束的信号标志置为true signal.imageSequenceOutputComplete = true; + // 构造ffmpeg脚本需要的路径变量(提前到配置) std::string fileName = "/%dresult.ppm"; filePath.totalImageOutputPath = filePath.deviceSpecFilePath + fileName; return; } - if (_access(filePath.deviceSpecFilePath.c_str(), 0) == -1) + // 路径存在性检查,不存在则创建 + if (!std::filesystem::exists(filePath.deviceSpecFilePath.c_str())) { std::filesystem::create_directories(filePath.deviceSpecFilePath.c_str()); } + // 拼接图片序列编号到路径里 std::string fileName ="/" + std::to_string(savedFrameCounter) + "result.ppm"; filePath.totalImageOutputPath = filePath.deviceSpecFilePath + fileName; //std::cout << outputPath << std::endl; + // 写入文件 writeImageToFile(filePath.totalImageOutputPath.c_str()); + // 写入一帧后已保存帧数+1 savedFrameCounter++; } void PlumageRender::imageSequenceToVideo() { + // 边界条件,图片序列输出未完成 if (!signal.imageSequenceOutputComplete) { return; } + // 边界条件,图片序列到视频的输出已完成 if (signal.imageSequenceToVideoComplete) { return; } + // 拼接视频保存的设备编号路径(提前到配置文件进行) std::string deviceFilePath = filePath.videoOutputPath + "/device" + std::to_string(selectedPhysicalDeviceIndex); - if (_access(deviceFilePath.c_str(), 0) == -1) + // 判断路径是否存在,不存在则创建 + if (std::filesystem::exists(deviceFilePath.c_str())) { std::filesystem::create_directories(deviceFilePath.c_str()); } - + // 构造结果视频路径 std::string resultVideoPath = deviceFilePath + "/result.mp4"; - + // 构造脚本需要参数,图片序列路径和设定的帧率 std::string commandLineImageSequencePath = filePath.totalImageOutputPath; //std::string commandLineCodecAndResultPath = resultVideoPath; std::string commandLineFrameRate = std::to_string(settings.videoFrameRate); + // 根据不同系统使用不同脚本 #if defined(_WIN32) std::string commandLine = filePath.image2videoBatFilePath + " " + commandLineFrameRate + " " + commandLineImageSequencePath + " " + resultVideoPath; #else @@ -1864,7 +1877,7 @@ PlumageRender::PlumageRender() #endif std::cout << commandLine << std::endl; std::system(commandLine.c_str()); - + // 视频输出完成,置标志为true signal.imageSequenceToVideoComplete = true; std::cout << "vidoe codec complete,saved in:" << resultVideoPath << std::endl; std::cout << "star to clean up image sequence" << std::endl; @@ -1873,14 +1886,17 @@ PlumageRender::PlumageRender() void PlumageRender::removeImageSequence() { + // 函数非第一次运行的边界条件 if (savedFrameCounter != settings.startFrameCount) { + // 检查视频输出完成的标志位 if (!signal.imageSequenceToVideoComplete) { return; } } + // 遍历删除图片序列文件和空文件夹 if (std::filesystem::exists(filePath.deviceSpecFilePath)) { for (const auto& entry : std::filesystem::directory_iterator(filePath.deviceSpecFilePath)) diff --git a/src/render/render.h b/src/render/render.h index 41e336d..5ef8de8 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -1,16 +1,5 @@ #pragma once - -#if defined(_WIN32) -#include -#include -#else -#include -#include -#endif - - - #include #include #include @@ -140,7 +129,11 @@ public: } pushConstBlockMaterial; struct FilePath - { //model path + { + + std::filesystem::path fallbackRootDataPath = "./data"; + + // model path std::string glTFModelFilePath = getAssetPath() + "models/DamagedHelmet/DamagedHelmet.gltf"; std::string modelVertShaderPath = getAssetPath() + "buster_drone/shaders/glsl/mesh.vert.spv"; std::string modelFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/mesh.frag.spv";