diff --git a/.clang-format b/.clang-format deleted file mode 100644 index 80f4f718b..000000000 --- a/.clang-format +++ /dev/null @@ -1,68 +0,0 @@ ---- -BasedOnStyle: Google -AccessModifierOffset: -2 -ConstructorInitializerIndentWidth: 2 -AlignEscapedNewlinesLeft: false -AlignTrailingComments: true -AllowAllParametersOfDeclarationOnNextLine: false -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AllowShortFunctionsOnASingleLine: None -AlwaysBreakTemplateDeclarations: true -AlwaysBreakBeforeMultilineStrings: false -BreakBeforeBinaryOperators: false -BreakBeforeTernaryOperators: false -BreakConstructorInitializers: BeforeComma -BinPackParameters: true -ColumnLimit: 90 -ConstructorInitializerAllOnOneLineOrOnePerLine: true -DerivePointerBinding: false -PointerBindsToType: true -ExperimentalAutoDetectBinPacking: false -IndentCaseLabels: true -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -ObjCSpaceBeforeProtocolList: true -PenaltyBreakBeforeFirstCallParameter: 19 -PenaltyBreakComment: 60 -PenaltyBreakString: 1 -PenaltyBreakFirstLessLess: 1000 -PenaltyExcessCharacter: 1000 -PenaltyReturnTypeOnItsOwnLine: 90 -SpacesBeforeTrailingComments: 2 -Cpp11BracedListStyle: false -Standard: Auto -IndentWidth: 2 -TabWidth: 2 -UseTab: Never -IndentFunctionDeclarationAfterType: false -SpacesInParentheses: false -SpacesInAngles: false -SpaceInEmptyParentheses: false -SpacesInCStyleCastParentheses: false -SpaceAfterControlStatementKeyword: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeParens: Never -ContinuationIndentWidth: 4 -SortIncludes: false -SpaceAfterCStyleCast: false -ReflowComments: false - -# Configure each individual brace in BraceWrapping -BreakBeforeBraces: Custom - -# Control of individual brace wrapping cases -BraceWrapping: { - AfterClass: 'true', - AfterControlStatement: 'true', - AfterEnum : 'true', - AfterFunction : 'true', - AfterNamespace : 'true', - AfterStruct : 'true', - AfterUnion : 'true', - BeforeCatch : 'true', - BeforeElse : 'true', - IndentBraces : 'false', - SplitEmptyFunction: 'false' -} -... diff --git a/.codespell_ignore_words b/.codespell_ignore_words deleted file mode 100644 index ab09b3c2f..000000000 --- a/.codespell_ignore_words +++ /dev/null @@ -1,7 +0,0 @@ -INOUT -InOut -delimeter -Succesful -worl -valu -Exeption diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index accb08cd7..000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,4 +0,0 @@ -# These are supported funding model platforms - -github: facontidavide -custom: https://www.paypal.me/facontidavide diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 9eb010608..000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: Bug report -about: Help me help you... -title: '' -labels: '' -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -If you are experiencing a crash, provide a backtrace (GDB or similar). - -*How to Reproduce** - -Please provide a specific description of how to reproduce the issue or source code that can be compiled and executed. Please attach a file/project that is easy to compile, don't copy and paste code snippets! - -Even better, create a Pull Request with a failing unit test. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 021458556..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index 27c6ae66a..000000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/.github/workflows/cmake_ubuntu.yml b/.github/workflows/cmake_ubuntu.yml deleted file mode 100644 index 41ed9a196..000000000 --- a/.github/workflows/cmake_ubuntu.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: cmake Ubuntu - -on: - push: - branches: - - master - pull_request: - types: [opened, synchronize, reopened] - -env: - # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) - BUILD_TYPE: Release - -jobs: - build: - # The CMake configure and build commands are platform agnostic and should work equally - # well on Windows or Mac. You can convert this to a matrix build if you need - # cross-platform coverage. - # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-22.04] - - steps: - - uses: actions/checkout@v2 - - - name: Install Conan - id: conan - uses: turtlebrowser/get-conan@main - - - name: Create default profile - run: conan profile detect - - - name: Create Build Environment - # Some projects don't allow in-source building, so create a separate build directory - # We'll use this as our working directory for all subsequent commands - run: cmake -E make_directory ${{github.workspace}}/build - - - name: Install conan dependencies - working-directory: ${{github.workspace}}/build - run: conan install ${{github.workspace}}/conanfile.txt -s build_type=${{env.BUILD_TYPE}} --build=missing - - - name: Configure CMake - shell: bash - working-directory: ${{github.workspace}}/build - run: cmake ${{github.workspace}} -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake - - - name: Build - shell: bash - working-directory: ${{github.workspace}}/build - run: cmake --build . --config ${{env.BUILD_TYPE}} - - - name: run test (Linux) - working-directory: ${{github.workspace}}/build/tests - run: ctest - - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v3 diff --git a/.github/workflows/cmake_windows.yml b/.github/workflows/cmake_windows.yml deleted file mode 100644 index 34f4f97ce..000000000 --- a/.github/workflows/cmake_windows.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: cmake Windows - -on: - push: - branches: - - master - pull_request: - types: [opened, synchronize, reopened] - -env: - # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) - BUILD_TYPE: Release - -jobs: - build: - # The CMake configure and build commands are platform agnostic and should work equally - # well on Windows or Mac. You can convert this to a matrix build if you need - # cross-platform coverage. - # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - - - name: Install Conan - id: conan - uses: turtlebrowser/get-conan@main - - - name: Create default profile - run: conan profile detect - - - name: Create Build Environment - # Some projects don't allow in-source building, so create a separate build directory - # We'll use this as our working directory for all subsequent commands - run: cmake -E make_directory ${{github.workspace}}/build - - - name: Install conan dependencies - working-directory: ${{github.workspace}}/build - run: conan install ${{github.workspace}}/conanfile.txt -s build_type=${{env.BUILD_TYPE}} --build=missing - - - name: Configure CMake - shell: bash - working-directory: ${{github.workspace}}/build - run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake - - - name: Build - working-directory: ${{github.workspace}}/build - shell: bash - run: cmake --build . --config ${{env.BUILD_TYPE}} - - - name: run test (Windows) - working-directory: ${{github.workspace}}/build - run: $env:PATH+=";${{env.BUILD_TYPE}}"; tests/${{env.BUILD_TYPE}}/behaviortree_cpp_test.exe diff --git a/.github/workflows/codeql.yml.bkp b/.github/workflows/codeql.yml.bkp deleted file mode 100644 index a76a623ca..000000000 --- a/.github/workflows/codeql.yml.bkp +++ /dev/null @@ -1,63 +0,0 @@ -name: "CodeQL" - -on: - push: - branches: [ 'master' ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ 'master' ] - schedule: - - cron: '36 19 * * 2' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'cpp' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - queries: +security-and-quality - - - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" diff --git a/.github/workflows/doxygen-gh-pages.yml b/.github/workflows/doxygen-gh-pages.yml deleted file mode 100644 index b8fb8f46b..000000000 --- a/.github/workflows/doxygen-gh-pages.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Doxygen GitHub Pages Deploy Action - -on: - push: - branches: - - main - - master - -jobs: - deploy: - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - uses: DenverCoder1/doxygen-github-pages-action@v2.0.0 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - folder: doc/html diff --git a/.github/workflows/pixi.yaml b/.github/workflows/pixi.yaml deleted file mode 100644 index ddd1cbfb8..000000000 --- a/.github/workflows/pixi.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: Pixi (conda) - -on: - push: - branches: - - master - pull_request: - types: [opened, synchronize, reopened] - -jobs: - pixi_conda_build: - strategy: - matrix: - os: - - windows-latest - - ubuntu-latest - runs-on: ${{ matrix.os }} - steps: - # Pixi is the tool used to create/manage conda environment - - uses: actions/checkout@v3 - - uses: prefix-dev/setup-pixi@v0.8.1 - with: - pixi-version: v0.40.3 - - name: Build - run: pixi run build - - name: Run tests - run: pixi run test diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml deleted file mode 100644 index ee7fa9229..000000000 --- a/.github/workflows/pre-commit.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: pre-commit - -on: - push: - branches: - - master - pull_request: - types: [opened, synchronize, reopened] - -jobs: - pre-commit: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 - - uses: pre-commit/action@v3.0.1 diff --git a/.github/workflows/ros2-rolling.yaml b/.github/workflows/ros2-rolling.yaml deleted file mode 100644 index 446c49879..000000000 --- a/.github/workflows/ros2-rolling.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: ros2-rolling - -on: - push: - branches: - - master - pull_request: - types: [opened, synchronize, reopened] - -jobs: - industrial_ci: - strategy: - matrix: - env: - - {ROS_DISTRO: rolling, ROS_REPO: main} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: 'ros-industrial/industrial_ci@master' - env: ${{matrix.env}} - with: - package-name: plotjuggler diff --git a/.github/workflows/ros2.yaml b/.github/workflows/ros2.yaml deleted file mode 100644 index 099cc04f2..000000000 --- a/.github/workflows/ros2.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: ros2 - -on: - push: - branches: - - master - pull_request: - types: [opened, synchronize, reopened] - -jobs: - industrial_ci: - strategy: - matrix: - env: - - {ROS_DISTRO: humble, ROS_REPO: main} - - {ROS_DISTRO: jazzy, ROS_REPO: main} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: 'ros-industrial/industrial_ci@master' - env: ${{matrix.env}} - with: - package-name: plotjuggler diff --git a/.github/workflows/sonarcube.yml.bkp b/.github/workflows/sonarcube.yml.bkp deleted file mode 100644 index 926306125..000000000 --- a/.github/workflows/sonarcube.yml.bkp +++ /dev/null @@ -1,42 +0,0 @@ -name: Sonarcube Scan - -on: - push: - branches: - - master - pull_request: - types: [opened, synchronize, reopened] - -jobs: - build: - name: Build - runs-on: ubuntu-latest - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - name: Install Build Wrapper - uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v4 - - - name: Install Dependencies - run: | - sudo apt-get update - sudo apt-get install -y libzmq3-dev libsqlite3-dev - - - name: Install googletest - uses: Bacondish2023/setup-googletest@v1 - - - name: Run Build Wrapper - run: | - mkdir build - cmake -S . -B build - build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build/ --config Release - - name: SonarQube Scan - uses: SonarSource/sonarqube-scan-action@v4 - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} # Put the name of your token here - with: - args: > - --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 9d5bd4326..000000000 --- a/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -*~ -/CMakeLists.txt.user -build* -site/* -/.vscode/ -.vs/ - -# clangd cache -/.cache/* -CMakeSettings.json - -# OSX junk -.DS_Store - -# pixi environments -.pixi - -CMakeUserPresets.json - -tags diff --git a/tests/gtest_scripting.cpp b/.nojekyll similarity index 100% rename from tests/gtest_scripting.cpp rename to .nojekyll diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index d491f36d9..000000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,54 +0,0 @@ - -# To use: -# -# pre-commit run -a -# -# Or: -# -# pre-commit install # (runs every time you commit in git) -# -# To update this file: -# -# pre-commit autoupdate -# -# See https://github.com/pre-commit/pre-commit - -exclude: ^3rdparty/|3rdparty|^include/behaviortree_cpp/contrib/ -repos: - - # Standard hooks - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 - hooks: - - id: check-added-large-files - - id: check-ast - - id: check-case-conflict - - id: check-docstring-first - - id: check-merge-conflict - - id: check-symlinks - - id: check-xml - - id: check-yaml - - id: debug-statements - - id: end-of-file-fixer - exclude_types: [svg] - - id: mixed-line-ending - - id: trailing-whitespace - exclude_types: [svg] - - id: fix-byte-order-marker - - # CPP hooks - - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v17.0.6 - hooks: - - id: clang-format - args: ['-fallback-style=none', '-i'] - - # Spell check - - repo: https://github.com/codespell-project/codespell - rev: v2.4.1 - hooks: - - id: codespell - additional_dependencies: - - tomli - args: - [--toml=./pyproject.toml] diff --git a/3rdparty/cppzmq/LICENSE b/3rdparty/cppzmq/LICENSE deleted file mode 100644 index ae98bd859..000000000 --- a/3rdparty/cppzmq/LICENSE +++ /dev/null @@ -1,17 +0,0 @@ - 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/3rdparty/cppzmq/README.md b/3rdparty/cppzmq/README.md deleted file mode 100644 index 5d804d0c8..000000000 --- a/3rdparty/cppzmq/README.md +++ /dev/null @@ -1,200 +0,0 @@ -[![CI](https://github.com/zeromq/cppzmq/actions/workflows/ci.yml/badge.svg)](https://github.com/zeromq/cppzmq/actions) -[![Coverage Status](https://coveralls.io/repos/github/zeromq/cppzmq/badge.svg?branch=master)](https://coveralls.io/github/zeromq/cppzmq?branch=master) -[![License](https://img.shields.io/github/license/zeromq/cppzmq.svg)](https://github.com/zeromq/cppzmq/blob/master/LICENSE) - -Introduction & Design Goals -=========================== - -cppzmq is a C++ binding for libzmq. It has the following design goals: - - cppzmq maps the libzmq C API to C++ concepts. In particular: - - it is type-safe (the libzmq C API exposes various class-like concepts as void*) - - it provides exception-based error handling (the libzmq C API provides errno-based error handling) - - it provides RAII-style classes that automate resource management (the libzmq C API requires the user to take care to free resources explicitly) - - cppzmq is a light-weight, header-only binding. You only need to include the header file zmq.hpp (and maybe zmq_addon.hpp) to use it. - - zmq.hpp is meant to contain direct mappings of the abstractions provided by the libzmq C API, while zmq_addon.hpp provides additional higher-level abstractions. - -There are other C++ bindings for ZeroMQ with different design goals. In particular, none of the following bindings are header-only: - - [zmqpp](https://github.com/zeromq/zmqpp) is a high-level binding to libzmq. - - [czmqpp](https://github.com/zeromq/czmqpp) is a binding based on the high-level czmq API. - - [fbzmq](https://github.com/facebook/fbzmq) is a binding that integrates with Apache Thrift and provides higher-level abstractions in addition. It requires C++14. - -Supported platforms -=================== - - - Only a subset of the platforms that are supported by libzmq itself are supported. Some features already require a compiler supporting C++11. In the future, probably all features will require C++11. To build and run the tests, CMake and Catch are required. - - Any libzmq 4.x version is expected to work. DRAFT features may only work for the most recent tested version. Currently explicitly tested libzmq versions are - - 4.2.0 (without DRAFT API) - - 4.3.4 (with and without DRAFT API) - - Platforms with full support (i.e. CI executing build and tests) - - Ubuntu 18.04 x64 (with gcc 4.8.5, 5.5.0, 7.5.0) - - Ubuntu 20.04 x64 (with gcc 9.3.0, 10.3.0 and clang 12) - - Visual Studio 2017 x64 - - Visual Studio 2019 x64 - - macOS 10.15 (with clang 12, without DRAFT API) - - Additional platforms that are known to work: - - We have no current reports on additional platforms that are known to work yet. Please add your platform here. If CI can be provided for them with a cloud-based CI service working with GitHub, you are invited to add CI, and make it possible to be included in the list above. - - Additional platforms that probably work: - - Any platform supported by libzmq that provides a sufficiently recent gcc (4.8.1 or newer) or clang (3.4.1 or newer) - - Visual Studio 2012+ x86/x64 - -Examples -======== -These examples require at least C++11. -```c++ -#include - -int main() -{ - zmq::context_t ctx; - zmq::socket_t sock(ctx, zmq::socket_type::push); - sock.bind("inproc://test"); - sock.send(zmq::str_buffer("Hello, world"), zmq::send_flags::dontwait); -} -``` -This a more complex example where we send and receive multi-part messages over TCP with a wildcard port. -```c++ -#include -#include - -int main() -{ - zmq::context_t ctx; - zmq::socket_t sock1(ctx, zmq::socket_type::push); - zmq::socket_t sock2(ctx, zmq::socket_type::pull); - sock1.bind("tcp://127.0.0.1:*"); - const std::string last_endpoint = - sock1.get(zmq::sockopt::last_endpoint); - std::cout << "Connecting to " - << last_endpoint << std::endl; - sock2.connect(last_endpoint); - - std::array send_msgs = { - zmq::str_buffer("foo"), - zmq::str_buffer("bar!") - }; - if (!zmq::send_multipart(sock1, send_msgs)) - return 1; - - std::vector recv_msgs; - const auto ret = zmq::recv_multipart( - sock2, std::back_inserter(recv_msgs)); - if (!ret) - return 1; - std::cout << "Got " << *ret - << " messages" << std::endl; - return 0; -} -``` - -See the `examples` directory for more examples. When the project is compiled with tests enabled, each example gets compiled to an executable. - - -API Overview -============ - -For an extensive overview of the `zmq.hpp` API in use, see this [Tour of CPPZMQ by @brettviren](https://brettviren.github.io/cppzmq-tour/index.html). - -Bindings for libzmq in `zmq.hpp`: - -Types: -* class `zmq::context_t` -* enum `zmq::ctxopt` -* class `zmq::socket_t` -* class `zmq::socket_ref` -* enum `zmq::socket_type` -* enum `zmq::sockopt` -* enum `zmq::send_flags` -* enum `zmq::recv_flags` -* class `zmq::message_t` -* class `zmq::const_buffer` -* class `zmq::mutable_buffer` -* struct `zmq::recv_buffer_size` -* alias `zmq::send_result_t` -* alias `zmq::recv_result_t` -* alias `zmq::recv_buffer_result_t` -* class `zmq::error_t` -* class `zmq::monitor_t` -* struct `zmq_event_t`, -* alias `zmq::free_fn`, -* alias `zmq::pollitem_t`, -* alias `zmq::fd_t` -* class `zmq::poller_t` DRAFT -* enum `zmq::event_flags` DRAFT -* enum `zmq::poller_event` DRAFT - -Functions: -* `zmq::version` -* `zmq::poll` -* `zmq::proxy` -* `zmq::proxy_steerable` -* `zmq::buffer` -* `zmq::str_buffer` - -Extra high-level types and functions `zmq_addon.hpp`: - -Types: -* class `zmq::multipart_t` -* class `zmq::active_poller_t` DRAFT - -Functions: -* `zmq::recv_multipart` -* `zmq::send_multipart` -* `zmq::send_multipart_n` -* `zmq::encode` -* `zmq::decode` - -Compatibility Guidelines -======================== - -The users of cppzmq are expected to follow the guidelines below to ensure not to break when upgrading cppzmq to newer versions (non-exhaustive list): - -* Do not depend on any macros defined in cppzmq unless explicitly declared public here. - -The following macros may be used by consumers of cppzmq: `CPPZMQ_VERSION`, `CPPZMQ_VERSION_MAJOR`, `CPPZMQ_VERSION_MINOR`, `CPPZMQ_VERSION_PATCH`. - -Contribution policy -=================== - -The contribution policy is at: http://rfc.zeromq.org/spec:22 - -Build instructions -================== - -Build steps: - -1. Build [libzmq](https://github.com/zeromq/libzmq) via cmake. This does an out of source build and installs the build files - - `git clone https://github.com/zeromq/libzmq.git` - - `cd libzmq` - - `mkdir build` - - `cd build` - - `cmake ..` - - `sudo make -j4 install` - -2. Build cppzmq via cmake. This does an out of source build and installs the build files - - `git clone https://github.com/zeromq/cppzmq.git` - - `cd cppzmq` - - `mkdir build` - - `cd build` - - `cmake ..` or `cmake -DCPPZMQ_BUILD_TESTS=OFF ..` to skip building tests - - `sudo make -j4 install` - -3. Alternatively, build cppzmq via [vcpkg](https://github.com/Microsoft/vcpkg/). This does an out of source build and installs the build files - - `git clone https://github.com/Microsoft/vcpkg.git` - - `cd vcpkg` - - `./bootstrap-vcpkg.sh` (bootstrap-vcpkg.bat for Powershell) - - `./vcpkg integrate install` - - `./vcpkg install cppzmq` - -Using this: - -A cmake find package scripts is provided for you to easily include this library. -Add these lines in your CMakeLists.txt to include the headers and library files of -cpp zmq (which will also include libzmq for you). - -``` -#find cppzmq wrapper, installed by make of cppzmq -find_package(cppzmq) -target_link_libraries(*Your Project Name* cppzmq) -# Or use static library to link -target_link_libraries(*Your Project Name* cppzmq-static) -``` diff --git a/3rdparty/cppzmq/zmq.hpp b/3rdparty/cppzmq/zmq.hpp deleted file mode 100644 index ad0509e89..000000000 --- a/3rdparty/cppzmq/zmq.hpp +++ /dev/null @@ -1,2879 +0,0 @@ -/* - Copyright (c) 2016-2017 ZeroMQ community - Copyright (c) 2009-2011 250bpm s.r.o. - Copyright (c) 2011 Botond Ballo - Copyright (c) 2007-2009 iMatix Corporation - - 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 __ZMQ_HPP_INCLUDED__ -#define __ZMQ_HPP_INCLUDED__ - -#ifdef _WIN32 -#ifndef NOMINMAX -#define NOMINMAX -#endif -#endif - -// included here for _HAS_CXX* macros -#include - -#if defined(_MSVC_LANG) -#define CPPZMQ_LANG _MSVC_LANG -#else -#define CPPZMQ_LANG __cplusplus -#endif -// overwrite if specific language macros indicate higher version -#if defined(_HAS_CXX14) && _HAS_CXX14 && CPPZMQ_LANG < 201402L -#undef CPPZMQ_LANG -#define CPPZMQ_LANG 201402L -#endif -#if defined(_HAS_CXX17) && _HAS_CXX17 && CPPZMQ_LANG < 201703L -#undef CPPZMQ_LANG -#define CPPZMQ_LANG 201703L -#endif - -// macros defined if has a specific standard or greater -#if CPPZMQ_LANG >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) -#define ZMQ_CPP11 -#endif -#if CPPZMQ_LANG >= 201402L -#define ZMQ_CPP14 -#endif -#if CPPZMQ_LANG >= 201703L -#define ZMQ_CPP17 -#endif - -#if defined(ZMQ_CPP14) && !defined(_MSC_VER) -#define ZMQ_DEPRECATED(msg) [[deprecated(msg)]] -#elif defined(_MSC_VER) -#define ZMQ_DEPRECATED(msg) __declspec(deprecated(msg)) -#elif defined(__GNUC__) -#define ZMQ_DEPRECATED(msg) __attribute__((deprecated(msg))) -#else -#define ZMQ_DEPRECATED(msg) -#endif - -#if defined(ZMQ_CPP17) -#define ZMQ_NODISCARD [[nodiscard]] -#else -#define ZMQ_NODISCARD -#endif - -#if defined(ZMQ_CPP11) -#define ZMQ_NOTHROW noexcept -#define ZMQ_EXPLICIT explicit -#define ZMQ_OVERRIDE override -#define ZMQ_NULLPTR nullptr -#define ZMQ_CONSTEXPR_FN constexpr -#define ZMQ_CONSTEXPR_VAR constexpr -#define ZMQ_CPP11_DEPRECATED(msg) ZMQ_DEPRECATED(msg) -#else -#define ZMQ_NOTHROW throw() -#define ZMQ_EXPLICIT -#define ZMQ_OVERRIDE -#define ZMQ_NULLPTR 0 -#define ZMQ_CONSTEXPR_FN -#define ZMQ_CONSTEXPR_VAR const -#define ZMQ_CPP11_DEPRECATED(msg) -#endif -#if defined(ZMQ_CPP14) && (!defined(_MSC_VER) || _MSC_VER > 1900) && (!defined(__GNUC__) || __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ > 3)) -#define ZMQ_EXTENDED_CONSTEXPR -#endif -#if defined(ZMQ_CPP17) -#define ZMQ_INLINE_VAR inline -#define ZMQ_CONSTEXPR_IF constexpr -#else -#define ZMQ_INLINE_VAR -#define ZMQ_CONSTEXPR_IF -#endif - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#ifdef ZMQ_CPP11 -#include -#include -#include -#include -#endif - -#if defined(__has_include) && defined(ZMQ_CPP17) -#define CPPZMQ_HAS_INCLUDE_CPP17(X) __has_include(X) -#else -#define CPPZMQ_HAS_INCLUDE_CPP17(X) 0 -#endif - -#if CPPZMQ_HAS_INCLUDE_CPP17() && !defined(CPPZMQ_HAS_OPTIONAL) -#define CPPZMQ_HAS_OPTIONAL 1 -#endif -#ifndef CPPZMQ_HAS_OPTIONAL -#define CPPZMQ_HAS_OPTIONAL 0 -#elif CPPZMQ_HAS_OPTIONAL -#include -#endif - -#if CPPZMQ_HAS_INCLUDE_CPP17() && !defined(CPPZMQ_HAS_STRING_VIEW) -#define CPPZMQ_HAS_STRING_VIEW 1 -#endif -#ifndef CPPZMQ_HAS_STRING_VIEW -#define CPPZMQ_HAS_STRING_VIEW 0 -#elif CPPZMQ_HAS_STRING_VIEW -#include -#endif - -/* Version macros for compile-time API version detection */ -#define CPPZMQ_VERSION_MAJOR 4 -#define CPPZMQ_VERSION_MINOR 11 -#define CPPZMQ_VERSION_PATCH 0 - -#define CPPZMQ_VERSION \ - ZMQ_MAKE_VERSION(CPPZMQ_VERSION_MAJOR, CPPZMQ_VERSION_MINOR, \ - CPPZMQ_VERSION_PATCH) - -// Detect whether the compiler supports C++11 rvalue references. -#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) \ - && defined(__GXX_EXPERIMENTAL_CXX0X__)) -#define ZMQ_HAS_RVALUE_REFS -#define ZMQ_DELETED_FUNCTION = delete -#elif defined(__clang__) -#if __has_feature(cxx_rvalue_references) -#define ZMQ_HAS_RVALUE_REFS -#endif - -#if __has_feature(cxx_deleted_functions) -#define ZMQ_DELETED_FUNCTION = delete -#else -#define ZMQ_DELETED_FUNCTION -#endif -#elif defined(_MSC_VER) && (_MSC_VER >= 1900) -#define ZMQ_HAS_RVALUE_REFS -#define ZMQ_DELETED_FUNCTION = delete -#elif defined(_MSC_VER) && (_MSC_VER >= 1600) -#define ZMQ_HAS_RVALUE_REFS -#define ZMQ_DELETED_FUNCTION -#else -#define ZMQ_DELETED_FUNCTION -#endif - -#if defined(ZMQ_CPP11) && !defined(__llvm__) && !defined(__INTEL_COMPILER) \ - && defined(__GNUC__) && __GNUC__ < 5 -#define ZMQ_CPP11_PARTIAL -#elif defined(__GLIBCXX__) && __GLIBCXX__ < 20160805 -//the date here is the last date of gcc 4.9.4, which -// effectively means libstdc++ from gcc 5.5 and higher won't trigger this branch -#define ZMQ_CPP11_PARTIAL -#endif - -#ifdef ZMQ_CPP11 -#ifdef ZMQ_CPP11_PARTIAL -#define ZMQ_IS_TRIVIALLY_COPYABLE(T) __has_trivial_copy(T) -#else -#include -#define ZMQ_IS_TRIVIALLY_COPYABLE(T) std::is_trivially_copyable::value -#endif -#endif - -#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3, 3, 0) -#define ZMQ_NEW_MONITOR_EVENT_LAYOUT -#endif - -#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 1, 0) -#define ZMQ_HAS_PROXY_STEERABLE -/* Socket event data */ -typedef struct -{ - uint16_t event; // id of the event as bitfield - int32_t value; // value is either error code, fd or reconnect interval -} zmq_event_t; -#endif - -// Avoid using deprecated message receive function when possible -#if ZMQ_VERSION < ZMQ_MAKE_VERSION(3, 2, 0) -#define zmq_msg_recv(msg, socket, flags) zmq_recvmsg(socket, msg, flags) -#endif - - -// In order to prevent unused variable warnings when building in non-debug -// mode use this macro to make assertions. -#ifndef NDEBUG -#define ZMQ_ASSERT(expression) assert(expression) -#else -#define ZMQ_ASSERT(expression) (void) (expression) -#endif - -namespace zmq -{ -#ifdef ZMQ_CPP11 -namespace detail -{ -namespace ranges -{ -using std::begin; -using std::end; -template auto begin(T &&r) -> decltype(begin(std::forward(r))) -{ - return begin(std::forward(r)); -} -template auto end(T &&r) -> decltype(end(std::forward(r))) -{ - return end(std::forward(r)); -} -} // namespace ranges - -template using void_t = void; - -template -using iter_value_t = typename std::iterator_traits::value_type; - -template -using range_iter_t = decltype( - ranges::begin(std::declval::type &>())); - -template using range_value_t = iter_value_t>; - -template struct is_range : std::false_type -{ -}; - -template -struct is_range< - T, - void_t::type &>()) - == ranges::end(std::declval::type &>()))>> - : std::true_type -{ -}; - -} // namespace detail -#endif - -typedef zmq_free_fn free_fn; -typedef zmq_pollitem_t pollitem_t; - -// duplicate definition from libzmq 4.3.3 -#if defined _WIN32 -#if defined _WIN64 -typedef unsigned __int64 fd_t; -#else -typedef unsigned int fd_t; -#endif -#else -typedef int fd_t; -#endif - -class error_t : public std::exception -{ - public: - error_t() ZMQ_NOTHROW : errnum(zmq_errno()) {} - explicit error_t(int err) ZMQ_NOTHROW : errnum(err) {} - virtual const char *what() const ZMQ_NOTHROW ZMQ_OVERRIDE - { - return zmq_strerror(errnum); - } - int num() const ZMQ_NOTHROW { return errnum; } - - private: - int errnum; -}; - -namespace detail { -inline int poll(zmq_pollitem_t *items_, size_t nitems_, long timeout_) -{ - int rc = zmq_poll(items_, static_cast(nitems_), timeout_); - if (rc < 0) - throw error_t(); - return rc; -} -} - -#ifdef ZMQ_CPP11 -ZMQ_DEPRECATED("from 4.8.0, use poll taking std::chrono::duration instead of long") -inline int poll(zmq_pollitem_t *items_, size_t nitems_, long timeout_) -#else -inline int poll(zmq_pollitem_t *items_, size_t nitems_, long timeout_ = -1) -#endif -{ - return detail::poll(items_, nitems_, timeout_); -} - -ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items") -inline int poll(zmq_pollitem_t const *items_, size_t nitems_, long timeout_ = -1) -{ - return detail::poll(const_cast(items_), nitems_, timeout_); -} - -#ifdef ZMQ_CPP11 -ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items") -inline int -poll(zmq_pollitem_t const *items, size_t nitems, std::chrono::milliseconds timeout) -{ - return detail::poll(const_cast(items), nitems, - static_cast(timeout.count())); -} - -ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items") -inline int poll(std::vector const &items, - std::chrono::milliseconds timeout) -{ - return detail::poll(const_cast(items.data()), items.size(), - static_cast(timeout.count())); -} - -ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items") -inline int poll(std::vector const &items, long timeout_ = -1) -{ - return detail::poll(const_cast(items.data()), items.size(), timeout_); -} - -inline int -poll(zmq_pollitem_t *items, size_t nitems, std::chrono::milliseconds timeout = std::chrono::milliseconds{-1}) -{ - return detail::poll(items, nitems, static_cast(timeout.count())); -} - -inline int poll(std::vector &items, - std::chrono::milliseconds timeout = std::chrono::milliseconds{-1}) -{ - return detail::poll(items.data(), items.size(), static_cast(timeout.count())); -} - -ZMQ_DEPRECATED("from 4.3.1, use poll taking std::chrono::duration instead of long") -inline int poll(std::vector &items, long timeout_) -{ - return detail::poll(items.data(), items.size(), timeout_); -} - -template -inline int poll(std::array &items, - std::chrono::milliseconds timeout = std::chrono::milliseconds{-1}) -{ - return detail::poll(items.data(), items.size(), static_cast(timeout.count())); -} -#endif - - -inline void version(int *major_, int *minor_, int *patch_) -{ - zmq_version(major_, minor_, patch_); -} - -#ifdef ZMQ_CPP11 -inline std::tuple version() -{ - std::tuple v; - zmq_version(&std::get<0>(v), &std::get<1>(v), &std::get<2>(v)); - return v; -} - -#if !defined(ZMQ_CPP11_PARTIAL) -namespace detail -{ -template struct is_char_type -{ - // true if character type for string literals in C++11 - static constexpr bool value = - std::is_same::value || std::is_same::value - || std::is_same::value || std::is_same::value; -}; -} -#endif - -#endif - -class message_t -{ - public: - message_t() ZMQ_NOTHROW - { - int rc = zmq_msg_init(&msg); - ZMQ_ASSERT(rc == 0); - } - - explicit message_t(size_t size_) - { - int rc = zmq_msg_init_size(&msg, size_); - if (rc != 0) - throw error_t(); - } - - template message_t(ForwardIter first, ForwardIter last) - { - typedef typename std::iterator_traits::value_type value_t; - - assert(std::distance(first, last) >= 0); - size_t const size_ = - static_cast(std::distance(first, last)) * sizeof(value_t); - int const rc = zmq_msg_init_size(&msg, size_); - if (rc != 0) - throw error_t(); - std::copy(first, last, data()); - } - - message_t(const void *data_, size_t size_) - { - int rc = zmq_msg_init_size(&msg, size_); - if (rc != 0) - throw error_t(); - if (size_) { - // this constructor allows (nullptr, 0), - // memcpy with a null pointer is UB - memcpy(data(), data_, size_); - } - } - - message_t(void *data_, size_t size_, free_fn *ffn_, void *hint_ = ZMQ_NULLPTR) - { - int rc = zmq_msg_init_data(&msg, data_, size_, ffn_, hint_); - if (rc != 0) - throw error_t(); - } - - // overload set of string-like types and generic containers -#if defined(ZMQ_CPP11) && !defined(ZMQ_CPP11_PARTIAL) - // NOTE this constructor will include the null terminator - // when called with a string literal. - // An overload taking const char* can not be added because - // it would be preferred over this function and break compatiblity. - template< - class Char, - size_t N, - typename = typename std::enable_if::value>::type> - ZMQ_DEPRECATED("from 4.7.0, use constructors taking iterators, (pointer, size) " - "or strings instead") - explicit message_t(const Char (&data)[N]) : - message_t(detail::ranges::begin(data), detail::ranges::end(data)) - { - } - - template::value - && ZMQ_IS_TRIVIALLY_COPYABLE(detail::range_value_t) - && !detail::is_char_type>::value - && !std::is_same::value>::type> - explicit message_t(const Range &rng) : - message_t(detail::ranges::begin(rng), detail::ranges::end(rng)) - { - } - - explicit message_t(const std::string &str) : message_t(str.data(), str.size()) {} - -#if CPPZMQ_HAS_STRING_VIEW - explicit message_t(std::string_view str) : message_t(str.data(), str.size()) {} -#endif - -#endif - -#ifdef ZMQ_HAS_RVALUE_REFS - message_t(message_t &&rhs) ZMQ_NOTHROW : msg(rhs.msg) - { - int rc = zmq_msg_init(&rhs.msg); - ZMQ_ASSERT(rc == 0); - } - - message_t &operator=(message_t &&rhs) ZMQ_NOTHROW - { - std::swap(msg, rhs.msg); - return *this; - } -#endif - - ~message_t() ZMQ_NOTHROW - { - int rc = zmq_msg_close(&msg); - ZMQ_ASSERT(rc == 0); - } - - void rebuild() - { - int rc = zmq_msg_close(&msg); - if (rc != 0) - throw error_t(); - rc = zmq_msg_init(&msg); - ZMQ_ASSERT(rc == 0); - } - - void rebuild(size_t size_) - { - int rc = zmq_msg_close(&msg); - if (rc != 0) - throw error_t(); - rc = zmq_msg_init_size(&msg, size_); - if (rc != 0) - throw error_t(); - } - - void rebuild(const void *data_, size_t size_) - { - int rc = zmq_msg_close(&msg); - if (rc != 0) - throw error_t(); - rc = zmq_msg_init_size(&msg, size_); - if (rc != 0) - throw error_t(); - memcpy(data(), data_, size_); - } - - void rebuild(const std::string &str) - { - rebuild(str.data(), str.size()); - } - - void rebuild(void *data_, size_t size_, free_fn *ffn_, void *hint_ = ZMQ_NULLPTR) - { - int rc = zmq_msg_close(&msg); - if (rc != 0) - throw error_t(); - rc = zmq_msg_init_data(&msg, data_, size_, ffn_, hint_); - if (rc != 0) - throw error_t(); - } - - ZMQ_DEPRECATED("from 4.3.1, use move taking non-const reference instead") - void move(message_t const *msg_) - { - int rc = zmq_msg_move(&msg, const_cast(msg_->handle())); - if (rc != 0) - throw error_t(); - } - - void move(message_t &msg_) - { - int rc = zmq_msg_move(&msg, msg_.handle()); - if (rc != 0) - throw error_t(); - } - - ZMQ_DEPRECATED("from 4.3.1, use copy taking non-const reference instead") - void copy(message_t const *msg_) - { - int rc = zmq_msg_copy(&msg, const_cast(msg_->handle())); - if (rc != 0) - throw error_t(); - } - - void copy(message_t &msg_) - { - int rc = zmq_msg_copy(&msg, msg_.handle()); - if (rc != 0) - throw error_t(); - } - - bool more() const ZMQ_NOTHROW - { - int rc = zmq_msg_more(const_cast(&msg)); - return rc != 0; - } - - void *data() ZMQ_NOTHROW { return zmq_msg_data(&msg); } - - const void *data() const ZMQ_NOTHROW - { - return zmq_msg_data(const_cast(&msg)); - } - - size_t size() const ZMQ_NOTHROW - { - return zmq_msg_size(const_cast(&msg)); - } - - ZMQ_NODISCARD bool empty() const ZMQ_NOTHROW { return size() == 0u; } - - template T *data() ZMQ_NOTHROW { return static_cast(data()); } - - template T const *data() const ZMQ_NOTHROW - { - return static_cast(data()); - } - - ZMQ_DEPRECATED("from 4.3.0, use operator== instead") - bool equal(const message_t *other) const ZMQ_NOTHROW { return *this == *other; } - - bool operator==(const message_t &other) const ZMQ_NOTHROW - { - const size_t my_size = size(); - return my_size == other.size() && 0 == memcmp(data(), other.data(), my_size); - } - - bool operator!=(const message_t &other) const ZMQ_NOTHROW - { - return !(*this == other); - } - -#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3, 2, 0) - int get(int property_) - { - int value = zmq_msg_get(&msg, property_); - if (value == -1) - throw error_t(); - return value; - } -#endif - -#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 1, 0) - const char *gets(const char *property_) - { - const char *value = zmq_msg_gets(&msg, property_); - if (value == ZMQ_NULLPTR) - throw error_t(); - return value; - } -#endif - -#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0) - uint32_t routing_id() const - { - return zmq_msg_routing_id(const_cast(&msg)); - } - - void set_routing_id(uint32_t routing_id) - { - int rc = zmq_msg_set_routing_id(&msg, routing_id); - if (rc != 0) - throw error_t(); - } - - const char *group() const - { - return zmq_msg_group(const_cast(&msg)); - } - - void set_group(const char *group) - { - int rc = zmq_msg_set_group(&msg, group); - if (rc != 0) - throw error_t(); - } -#endif - - // interpret message content as a string - std::string to_string() const - { - return std::string(static_cast(data()), size()); - } -#if CPPZMQ_HAS_STRING_VIEW - // interpret message content as a string - std::string_view to_string_view() const noexcept - { - return std::string_view(static_cast(data()), size()); - } -#endif - - /** Dump content to string for debugging. - * Ascii chars are readable, the rest is printed as hex. - * Probably ridiculously slow. - * Use to_string() or to_string_view() for - * interpreting the message as a string. - */ - std::string str(size_t max_size = 1000) const - { - // Partly mutuated from the same method in zmq::multipart_t - std::stringstream os; - - const unsigned char *msg_data = this->data(); - size_t size_to_print = (std::min)(this->size(), max_size); - int is_ascii[2] = {0, 0}; - // Set is_ascii for the first character - if (size_to_print > 0) - is_ascii[0] = (*msg_data >= 32 && *msg_data < 127); - - os << "zmq::message_t [size " << std::dec << std::setw(3) - << std::setfill('0') << this->size() << "] ("; - while (size_to_print--) { - const unsigned char byte = *msg_data++; - - is_ascii[1] = (byte >= 32 && byte < 127); - if (is_ascii[1] != is_ascii[0]) - os << " "; // Separate text/non text - - if (is_ascii[1]) { - os << byte; - } else { - os << std::hex << std::uppercase << std::setw(2) << std::setfill('0') - << static_cast(byte); - } - is_ascii[0] = is_ascii[1]; - } - // Elide the rest if the message is too large - if (max_size < this->size()) - os << "... too big to print)"; - else - os << ")"; - return os.str(); - } - - void swap(message_t &other) ZMQ_NOTHROW - { - // this assumes zmq::msg_t from libzmq is trivially relocatable - std::swap(msg, other.msg); - } - - ZMQ_NODISCARD zmq_msg_t *handle() ZMQ_NOTHROW { return &msg; } - ZMQ_NODISCARD const zmq_msg_t *handle() const ZMQ_NOTHROW { return &msg; } - - private: - // The underlying message - zmq_msg_t msg; - - // Disable implicit message copying, so that users won't use shared - // messages (less efficient) without being aware of the fact. - message_t(const message_t &) ZMQ_DELETED_FUNCTION; - void operator=(const message_t &) ZMQ_DELETED_FUNCTION; -}; - -inline void swap(message_t &a, message_t &b) ZMQ_NOTHROW -{ - a.swap(b); -} - -#ifdef ZMQ_CPP11 -enum class ctxopt -{ -#ifdef ZMQ_BLOCKY - blocky = ZMQ_BLOCKY, -#endif -#ifdef ZMQ_IO_THREADS - io_threads = ZMQ_IO_THREADS, -#endif -#ifdef ZMQ_THREAD_SCHED_POLICY - thread_sched_policy = ZMQ_THREAD_SCHED_POLICY, -#endif -#ifdef ZMQ_THREAD_PRIORITY - thread_priority = ZMQ_THREAD_PRIORITY, -#endif -#ifdef ZMQ_THREAD_AFFINITY_CPU_ADD - thread_affinity_cpu_add = ZMQ_THREAD_AFFINITY_CPU_ADD, -#endif -#ifdef ZMQ_THREAD_AFFINITY_CPU_REMOVE - thread_affinity_cpu_remove = ZMQ_THREAD_AFFINITY_CPU_REMOVE, -#endif -#ifdef ZMQ_THREAD_NAME_PREFIX - thread_name_prefix = ZMQ_THREAD_NAME_PREFIX, -#endif -#ifdef ZMQ_MAX_MSGSZ - max_msgsz = ZMQ_MAX_MSGSZ, -#endif -#ifdef ZMQ_ZERO_COPY_RECV - zero_copy_recv = ZMQ_ZERO_COPY_RECV, -#endif -#ifdef ZMQ_MAX_SOCKETS - max_sockets = ZMQ_MAX_SOCKETS, -#endif -#ifdef ZMQ_SOCKET_LIMIT - socket_limit = ZMQ_SOCKET_LIMIT, -#endif -#ifdef ZMQ_IPV6 - ipv6 = ZMQ_IPV6, -#endif -#ifdef ZMQ_MSG_T_SIZE - msg_t_size = ZMQ_MSG_T_SIZE -#endif -}; -#endif - -class context_t -{ - public: - context_t() - { - ptr = zmq_ctx_new(); - if (ptr == ZMQ_NULLPTR) - throw error_t(); - } - - - explicit context_t(int io_threads_, int max_sockets_ = ZMQ_MAX_SOCKETS_DFLT) - { - ptr = zmq_ctx_new(); - if (ptr == ZMQ_NULLPTR) - throw error_t(); - - int rc = zmq_ctx_set(ptr, ZMQ_IO_THREADS, io_threads_); - ZMQ_ASSERT(rc == 0); - - rc = zmq_ctx_set(ptr, ZMQ_MAX_SOCKETS, max_sockets_); - ZMQ_ASSERT(rc == 0); - } - -#ifdef ZMQ_HAS_RVALUE_REFS - context_t(context_t &&rhs) ZMQ_NOTHROW : ptr(rhs.ptr) { rhs.ptr = ZMQ_NULLPTR; } - context_t &operator=(context_t &&rhs) ZMQ_NOTHROW - { - close(); - std::swap(ptr, rhs.ptr); - return *this; - } -#endif - - ~context_t() ZMQ_NOTHROW { close(); } - - ZMQ_CPP11_DEPRECATED("from 4.7.0, use set taking zmq::ctxopt instead") - int setctxopt(int option_, int optval_) - { - int rc = zmq_ctx_set(ptr, option_, optval_); - ZMQ_ASSERT(rc == 0); - return rc; - } - - ZMQ_CPP11_DEPRECATED("from 4.7.0, use get taking zmq::ctxopt instead") - int getctxopt(int option_) { return zmq_ctx_get(ptr, option_); } - -#ifdef ZMQ_CPP11 - void set(ctxopt option, int optval) - { - int rc = zmq_ctx_set(ptr, static_cast(option), optval); - if (rc == -1) - throw error_t(); - } - - ZMQ_NODISCARD int get(ctxopt option) - { - int rc = zmq_ctx_get(ptr, static_cast(option)); - // some options have a default value of -1 - // which is unfortunate, and may result in errors - // that don't make sense - if (rc == -1) - throw error_t(); - return rc; - } -#endif - - // Terminates context (see also shutdown()). - void close() ZMQ_NOTHROW - { - if (ptr == ZMQ_NULLPTR) - return; - - int rc; - do { - rc = zmq_ctx_term(ptr); - } while (rc == -1 && errno == EINTR); - - ZMQ_ASSERT(rc == 0); - ptr = ZMQ_NULLPTR; - } - - // Shutdown context in preparation for termination (close()). - // Causes all blocking socket operations and any further - // socket operations to return with ETERM. - void shutdown() ZMQ_NOTHROW - { - if (ptr == ZMQ_NULLPTR) - return; - int rc = zmq_ctx_shutdown(ptr); - ZMQ_ASSERT(rc == 0); - } - - // Be careful with this, it's probably only useful for - // using the C api together with an existing C++ api. - // Normally you should never need to use this. - ZMQ_EXPLICIT operator void *() ZMQ_NOTHROW { return ptr; } - - ZMQ_EXPLICIT operator void const *() const ZMQ_NOTHROW { return ptr; } - - ZMQ_NODISCARD void *handle() ZMQ_NOTHROW { return ptr; } - - ZMQ_DEPRECATED("from 4.7.0, use handle() != nullptr instead") - operator bool() const ZMQ_NOTHROW { return ptr != ZMQ_NULLPTR; } - - void swap(context_t &other) ZMQ_NOTHROW { std::swap(ptr, other.ptr); } - - private: - void *ptr; - - context_t(const context_t &) ZMQ_DELETED_FUNCTION; - void operator=(const context_t &) ZMQ_DELETED_FUNCTION; -}; - -inline void swap(context_t &a, context_t &b) ZMQ_NOTHROW -{ - a.swap(b); -} - -#ifdef ZMQ_CPP11 - -struct recv_buffer_size -{ - size_t size; // number of bytes written to buffer - size_t untruncated_size; // untruncated message size in bytes - - ZMQ_NODISCARD bool truncated() const noexcept - { - return size != untruncated_size; - } -}; - -#if CPPZMQ_HAS_OPTIONAL - -using send_result_t = std::optional; -using recv_result_t = std::optional; -using recv_buffer_result_t = std::optional; - -#else - -namespace detail -{ -// A C++11 type emulating the most basic -// operations of std::optional for trivial types -template class trivial_optional -{ - public: - static_assert(std::is_trivial::value, "T must be trivial"); - using value_type = T; - - trivial_optional() = default; - trivial_optional(T value) noexcept : _value(value), _has_value(true) {} - - const T *operator->() const noexcept - { - assert(_has_value); - return &_value; - } - T *operator->() noexcept - { - assert(_has_value); - return &_value; - } - - const T &operator*() const noexcept - { - assert(_has_value); - return _value; - } - T &operator*() noexcept - { - assert(_has_value); - return _value; - } - - T &value() - { - if (!_has_value) - throw std::exception(); - return _value; - } - const T &value() const - { - if (!_has_value) - throw std::exception(); - return _value; - } - - explicit operator bool() const noexcept { return _has_value; } - bool has_value() const noexcept { return _has_value; } - - private: - T _value{}; - bool _has_value{false}; -}; -} // namespace detail - -using send_result_t = detail::trivial_optional; -using recv_result_t = detail::trivial_optional; -using recv_buffer_result_t = detail::trivial_optional; - -#endif - -namespace detail -{ -template constexpr T enum_bit_or(T a, T b) noexcept -{ - static_assert(std::is_enum::value, "must be enum"); - using U = typename std::underlying_type::type; - return static_cast(static_cast(a) | static_cast(b)); -} -template constexpr T enum_bit_and(T a, T b) noexcept -{ - static_assert(std::is_enum::value, "must be enum"); - using U = typename std::underlying_type::type; - return static_cast(static_cast(a) & static_cast(b)); -} -template constexpr T enum_bit_xor(T a, T b) noexcept -{ - static_assert(std::is_enum::value, "must be enum"); - using U = typename std::underlying_type::type; - return static_cast(static_cast(a) ^ static_cast(b)); -} -template constexpr T enum_bit_not(T a) noexcept -{ - static_assert(std::is_enum::value, "must be enum"); - using U = typename std::underlying_type::type; - return static_cast(~static_cast(a)); -} -} // namespace detail - -// partially satisfies named requirement BitmaskType -enum class send_flags : int -{ - none = 0, - dontwait = ZMQ_DONTWAIT, - sndmore = ZMQ_SNDMORE -}; - -constexpr send_flags operator|(send_flags a, send_flags b) noexcept -{ - return detail::enum_bit_or(a, b); -} -constexpr send_flags operator&(send_flags a, send_flags b) noexcept -{ - return detail::enum_bit_and(a, b); -} -constexpr send_flags operator^(send_flags a, send_flags b) noexcept -{ - return detail::enum_bit_xor(a, b); -} -constexpr send_flags operator~(send_flags a) noexcept -{ - return detail::enum_bit_not(a); -} - -// partially satisfies named requirement BitmaskType -enum class recv_flags : int -{ - none = 0, - dontwait = ZMQ_DONTWAIT -}; - -constexpr recv_flags operator|(recv_flags a, recv_flags b) noexcept -{ - return detail::enum_bit_or(a, b); -} -constexpr recv_flags operator&(recv_flags a, recv_flags b) noexcept -{ - return detail::enum_bit_and(a, b); -} -constexpr recv_flags operator^(recv_flags a, recv_flags b) noexcept -{ - return detail::enum_bit_xor(a, b); -} -constexpr recv_flags operator~(recv_flags a) noexcept -{ - return detail::enum_bit_not(a); -} - - -// mutable_buffer, const_buffer and buffer are based on -// the Networking TS specification, draft: -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4771.pdf - -class mutable_buffer -{ - public: - constexpr mutable_buffer() noexcept : _data(nullptr), _size(0) {} - constexpr mutable_buffer(void *p, size_t n) noexcept : _data(p), _size(n) - { -#ifdef ZMQ_EXTENDED_CONSTEXPR - assert(p != nullptr || n == 0); -#endif - } - - constexpr void *data() const noexcept { return _data; } - constexpr size_t size() const noexcept { return _size; } - mutable_buffer &operator+=(size_t n) noexcept - { - // (std::min) is a workaround for when a min macro is defined - const auto shift = (std::min)(n, _size); - _data = static_cast(_data) + shift; - _size -= shift; - return *this; - } - - private: - void *_data; - size_t _size; -}; - -inline mutable_buffer operator+(const mutable_buffer &mb, size_t n) noexcept -{ - return mutable_buffer(static_cast(mb.data()) + (std::min)(n, mb.size()), - mb.size() - (std::min)(n, mb.size())); -} -inline mutable_buffer operator+(size_t n, const mutable_buffer &mb) noexcept -{ - return mb + n; -} - -class const_buffer -{ - public: - constexpr const_buffer() noexcept : _data(nullptr), _size(0) {} - constexpr const_buffer(const void *p, size_t n) noexcept : _data(p), _size(n) - { -#ifdef ZMQ_EXTENDED_CONSTEXPR - assert(p != nullptr || n == 0); -#endif - } - constexpr const_buffer(const mutable_buffer &mb) noexcept : - _data(mb.data()), _size(mb.size()) - { - } - - constexpr const void *data() const noexcept { return _data; } - constexpr size_t size() const noexcept { return _size; } - const_buffer &operator+=(size_t n) noexcept - { - const auto shift = (std::min)(n, _size); - _data = static_cast(_data) + shift; - _size -= shift; - return *this; - } - - private: - const void *_data; - size_t _size; -}; - -inline const_buffer operator+(const const_buffer &cb, size_t n) noexcept -{ - return const_buffer(static_cast(cb.data()) - + (std::min)(n, cb.size()), - cb.size() - (std::min)(n, cb.size())); -} -inline const_buffer operator+(size_t n, const const_buffer &cb) noexcept -{ - return cb + n; -} - -// buffer creation - -constexpr mutable_buffer buffer(void *p, size_t n) noexcept -{ - return mutable_buffer(p, n); -} -constexpr const_buffer buffer(const void *p, size_t n) noexcept -{ - return const_buffer(p, n); -} -constexpr mutable_buffer buffer(const mutable_buffer &mb) noexcept -{ - return mb; -} -inline mutable_buffer buffer(const mutable_buffer &mb, size_t n) noexcept -{ - return mutable_buffer(mb.data(), (std::min)(mb.size(), n)); -} -constexpr const_buffer buffer(const const_buffer &cb) noexcept -{ - return cb; -} -inline const_buffer buffer(const const_buffer &cb, size_t n) noexcept -{ - return const_buffer(cb.data(), (std::min)(cb.size(), n)); -} - -namespace detail -{ -template struct is_buffer -{ - static constexpr bool value = - std::is_same::value || std::is_same::value; -}; - -template struct is_pod_like -{ - // NOTE: The networking draft N4771 section 16.11 requires - // T in the buffer functions below to be - // trivially copyable OR standard layout. - // Here we decide to be conservative and require both. - static constexpr bool value = - ZMQ_IS_TRIVIALLY_COPYABLE(T) && std::is_standard_layout::value; -}; - -template constexpr auto seq_size(const C &c) noexcept -> decltype(c.size()) -{ - return c.size(); -} -template -constexpr size_t seq_size(const T (&/*array*/)[N]) noexcept -{ - return N; -} - -template -auto buffer_contiguous_sequence(Seq &&seq) noexcept - -> decltype(buffer(std::addressof(*std::begin(seq)), size_t{})) -{ - using T = typename std::remove_cv< - typename std::remove_reference::type>::type; - static_assert(detail::is_pod_like::value, "T must be POD"); - - const auto size = seq_size(seq); - return buffer(size != 0u ? std::addressof(*std::begin(seq)) : nullptr, - size * sizeof(T)); -} -template -auto buffer_contiguous_sequence(Seq &&seq, size_t n_bytes) noexcept - -> decltype(buffer_contiguous_sequence(seq)) -{ - using T = typename std::remove_cv< - typename std::remove_reference::type>::type; - static_assert(detail::is_pod_like::value, "T must be POD"); - - const auto size = seq_size(seq); - return buffer(size != 0u ? std::addressof(*std::begin(seq)) : nullptr, - (std::min)(size * sizeof(T), n_bytes)); -} - -} // namespace detail - -// C array -template mutable_buffer buffer(T (&data)[N]) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -mutable_buffer buffer(T (&data)[N], size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -template const_buffer buffer(const T (&data)[N]) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -const_buffer buffer(const T (&data)[N], size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -// std::array -template mutable_buffer buffer(std::array &data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -mutable_buffer buffer(std::array &data, size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -template -const_buffer buffer(std::array &data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -const_buffer buffer(std::array &data, size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -template -const_buffer buffer(const std::array &data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -const_buffer buffer(const std::array &data, size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -// std::vector -template -mutable_buffer buffer(std::vector &data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -mutable_buffer buffer(std::vector &data, size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -template -const_buffer buffer(const std::vector &data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -const_buffer buffer(const std::vector &data, size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -// std::basic_string -template -mutable_buffer buffer(std::basic_string &data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -mutable_buffer buffer(std::basic_string &data, - size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -template -const_buffer buffer(const std::basic_string &data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -const_buffer buffer(const std::basic_string &data, - size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} - -#if CPPZMQ_HAS_STRING_VIEW -// std::basic_string_view -template -const_buffer buffer(std::basic_string_view data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -const_buffer buffer(std::basic_string_view data, size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -#endif - -// Buffer for a string literal (null terminated) -// where the buffer size excludes the terminating character. -// Equivalent to zmq::buffer(std::string_view("...")). -template -constexpr const_buffer str_buffer(const Char (&data)[N]) noexcept -{ - static_assert(detail::is_pod_like::value, "Char must be POD"); -#ifdef ZMQ_EXTENDED_CONSTEXPR - assert(data[N - 1] == Char{0}); -#endif - return const_buffer(static_cast(data), (N - 1) * sizeof(Char)); -} - -namespace literals -{ -constexpr const_buffer operator""_zbuf(const char *str, size_t len) noexcept -{ - return const_buffer(str, len * sizeof(char)); -} -constexpr const_buffer operator""_zbuf(const wchar_t *str, size_t len) noexcept -{ - return const_buffer(str, len * sizeof(wchar_t)); -} -constexpr const_buffer operator""_zbuf(const char16_t *str, size_t len) noexcept -{ - return const_buffer(str, len * sizeof(char16_t)); -} -constexpr const_buffer operator""_zbuf(const char32_t *str, size_t len) noexcept -{ - return const_buffer(str, len * sizeof(char32_t)); -} -} - -#ifdef ZMQ_CPP11 -enum class socket_type : int -{ - req = ZMQ_REQ, - rep = ZMQ_REP, - dealer = ZMQ_DEALER, - router = ZMQ_ROUTER, - pub = ZMQ_PUB, - sub = ZMQ_SUB, - xpub = ZMQ_XPUB, - xsub = ZMQ_XSUB, - push = ZMQ_PUSH, - pull = ZMQ_PULL, -#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0) - server = ZMQ_SERVER, - client = ZMQ_CLIENT, - radio = ZMQ_RADIO, - dish = ZMQ_DISH, - gather = ZMQ_GATHER, - scatter = ZMQ_SCATTER, - dgram = ZMQ_DGRAM, -#endif -#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 3, 3) - peer = ZMQ_PEER, - channel = ZMQ_CHANNEL, -#endif -#if ZMQ_VERSION_MAJOR >= 4 - stream = ZMQ_STREAM, -#endif - pair = ZMQ_PAIR -}; -#endif - -namespace sockopt -{ -// There are two types of options, -// integral type with known compiler time size (int, bool, int64_t, uint64_t) -// and arrays with dynamic size (strings, binary data). - -// BoolUnit: if true accepts values of type bool (but passed as T into libzmq) -template struct integral_option -{ -}; - -// NullTerm: -// 0: binary data -// 1: null-terminated string (`getsockopt` size includes null) -// 2: binary (size 32) or Z85 encoder string of size 41 (null included) -template struct array_option -{ -}; - -#define ZMQ_DEFINE_INTEGRAL_OPT(OPT, NAME, TYPE) \ - using NAME##_t = integral_option; \ - ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME {} -#define ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(OPT, NAME, TYPE) \ - using NAME##_t = integral_option; \ - ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME {} -#define ZMQ_DEFINE_ARRAY_OPT(OPT, NAME) \ - using NAME##_t = array_option; \ - ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME {} -#define ZMQ_DEFINE_ARRAY_OPT_BINARY(OPT, NAME) \ - using NAME##_t = array_option; \ - ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME {} -#define ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(OPT, NAME) \ - using NAME##_t = array_option; \ - ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME {} - -// deprecated, use zmq::fd_t -using cppzmq_fd_t = ::zmq::fd_t; - -#ifdef ZMQ_AFFINITY -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_AFFINITY, affinity, uint64_t); -#endif -#ifdef ZMQ_BACKLOG -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_BACKLOG, backlog, int); -#endif -#ifdef ZMQ_BINDTODEVICE -ZMQ_DEFINE_ARRAY_OPT_BINARY(ZMQ_BINDTODEVICE, bindtodevice); -#endif -#ifdef ZMQ_BUSY_POLL -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_BUSY_POLL, busy_poll, int); -#endif -#ifdef ZMQ_CONFLATE -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_CONFLATE, conflate, int); -#endif -#ifdef ZMQ_CONNECT_ROUTING_ID -ZMQ_DEFINE_ARRAY_OPT(ZMQ_CONNECT_ROUTING_ID, connect_routing_id); -#endif -#ifdef ZMQ_CONNECT_TIMEOUT -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_CONNECT_TIMEOUT, connect_timeout, int); -#endif -#ifdef ZMQ_CURVE_PUBLICKEY -ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(ZMQ_CURVE_PUBLICKEY, curve_publickey); -#endif -#ifdef ZMQ_CURVE_SECRETKEY -ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(ZMQ_CURVE_SECRETKEY, curve_secretkey); -#endif -#ifdef ZMQ_CURVE_SERVER -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_CURVE_SERVER, curve_server, int); -#endif -#ifdef ZMQ_CURVE_SERVERKEY -ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(ZMQ_CURVE_SERVERKEY, curve_serverkey); -#endif -#ifdef ZMQ_DISCONNECT_MSG -ZMQ_DEFINE_ARRAY_OPT_BINARY(ZMQ_DISCONNECT_MSG, disconnect_msg); -#endif -#ifdef ZMQ_EVENTS -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_EVENTS, events, int); -#endif -#ifdef ZMQ_FD -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_FD, fd, ::zmq::fd_t); -#endif -#ifdef ZMQ_GSSAPI_PLAINTEXT -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_GSSAPI_PLAINTEXT, gssapi_plaintext, int); -#endif -#ifdef ZMQ_GSSAPI_SERVER -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_GSSAPI_SERVER, gssapi_server, int); -#endif -#ifdef ZMQ_GSSAPI_SERVICE_PRINCIPAL -ZMQ_DEFINE_ARRAY_OPT(ZMQ_GSSAPI_SERVICE_PRINCIPAL, gssapi_service_principal); -#endif -#ifdef ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE, - gssapi_service_principal_nametype, - int); -#endif -#ifdef ZMQ_GSSAPI_PRINCIPAL -ZMQ_DEFINE_ARRAY_OPT(ZMQ_GSSAPI_PRINCIPAL, gssapi_principal); -#endif -#ifdef ZMQ_GSSAPI_PRINCIPAL_NAMETYPE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_GSSAPI_PRINCIPAL_NAMETYPE, - gssapi_principal_nametype, - int); -#endif -#ifdef ZMQ_HANDSHAKE_IVL -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HANDSHAKE_IVL, handshake_ivl, int); -#endif -#ifdef ZMQ_HEARTBEAT_IVL -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HEARTBEAT_IVL, heartbeat_ivl, int); -#endif -#ifdef ZMQ_HEARTBEAT_TIMEOUT -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HEARTBEAT_TIMEOUT, heartbeat_timeout, int); -#endif -#ifdef ZMQ_HEARTBEAT_TTL -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HEARTBEAT_TTL, heartbeat_ttl, int); -#endif -#ifdef ZMQ_HELLO_MSG -ZMQ_DEFINE_ARRAY_OPT_BINARY(ZMQ_HELLO_MSG, hello_msg); -#endif -#ifdef ZMQ_IMMEDIATE -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_IMMEDIATE, immediate, int); -#endif -#ifdef ZMQ_INVERT_MATCHING -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_INVERT_MATCHING, invert_matching, int); -#endif -#ifdef ZMQ_IPV6 -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_IPV6, ipv6, int); -#endif -#ifdef ZMQ_LAST_ENDPOINT -ZMQ_DEFINE_ARRAY_OPT(ZMQ_LAST_ENDPOINT, last_endpoint); -#endif -#ifdef ZMQ_LINGER -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_LINGER, linger, int); -#endif -#ifdef ZMQ_MAXMSGSIZE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MAXMSGSIZE, maxmsgsize, int64_t); -#endif -#ifdef ZMQ_MECHANISM -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MECHANISM, mechanism, int); -#endif -#ifdef ZMQ_METADATA -ZMQ_DEFINE_ARRAY_OPT(ZMQ_METADATA, metadata); -#endif -#ifdef ZMQ_MULTICAST_HOPS -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MULTICAST_HOPS, multicast_hops, int); -#endif -#ifdef ZMQ_MULTICAST_LOOP -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_MULTICAST_LOOP, multicast_loop, int); -#endif -#ifdef ZMQ_MULTICAST_MAXTPDU -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MULTICAST_MAXTPDU, multicast_maxtpdu, int); -#endif -#ifdef ZMQ_ONLY_FIRST_SUBSCRIBE -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ONLY_FIRST_SUBSCRIBE, only_first_subscribe, int); -#endif -#ifdef ZMQ_PLAIN_SERVER -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_PLAIN_SERVER, plain_server, int); -#endif -#ifdef ZMQ_PLAIN_PASSWORD -ZMQ_DEFINE_ARRAY_OPT(ZMQ_PLAIN_PASSWORD, plain_password); -#endif -#ifdef ZMQ_PLAIN_USERNAME -ZMQ_DEFINE_ARRAY_OPT(ZMQ_PLAIN_USERNAME, plain_username); -#endif -#ifdef ZMQ_PRIORITY -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_PRIORITY, priority, int); -#endif -#ifdef ZMQ_USE_FD -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_USE_FD, use_fd, int); -#endif -#ifdef ZMQ_PROBE_ROUTER -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_PROBE_ROUTER, probe_router, int); -#endif -#ifdef ZMQ_RATE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RATE, rate, int); -#endif -#ifdef ZMQ_RCVBUF -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RCVBUF, rcvbuf, int); -#endif -#ifdef ZMQ_RCVHWM -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RCVHWM, rcvhwm, int); -#endif -#ifdef ZMQ_RCVMORE -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_RCVMORE, rcvmore, int); -#endif -#ifdef ZMQ_RCVTIMEO -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RCVTIMEO, rcvtimeo, int); -#endif -#ifdef ZMQ_RECONNECT_IVL -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECONNECT_IVL, reconnect_ivl, int); -#endif -#ifdef ZMQ_RECONNECT_IVL_MAX -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECONNECT_IVL_MAX, reconnect_ivl_max, int); -#endif -#ifdef ZMQ_RECONNECT_STOP -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECONNECT_STOP, reconnect_stop, int); -#endif -#ifdef ZMQ_RECOVERY_IVL -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECOVERY_IVL, recovery_ivl, int); -#endif -#ifdef ZMQ_REQ_CORRELATE -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_REQ_CORRELATE, req_correlate, int); -#endif -#ifdef ZMQ_REQ_RELAXED -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_REQ_RELAXED, req_relaxed, int); -#endif -#ifdef ZMQ_ROUTER_HANDOVER -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ROUTER_HANDOVER, router_handover, int); -#endif -#ifdef ZMQ_ROUTER_MANDATORY -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ROUTER_MANDATORY, router_mandatory, int); -#endif -#ifdef ZMQ_ROUTER_NOTIFY -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_ROUTER_NOTIFY, router_notify, int); -#endif -#ifdef ZMQ_ROUTER_RAW -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_ROUTER_RAW, router_raw, int); -#endif -#ifdef ZMQ_ROUTING_ID -ZMQ_DEFINE_ARRAY_OPT_BINARY(ZMQ_ROUTING_ID, routing_id); -#endif -#ifdef ZMQ_SNDBUF -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_SNDBUF, sndbuf, int); -#endif -#ifdef ZMQ_SNDHWM -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_SNDHWM, sndhwm, int); -#endif -#ifdef ZMQ_SNDTIMEO -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_SNDTIMEO, sndtimeo, int); -#endif -#ifdef ZMQ_SOCKS_PASSWORD -ZMQ_DEFINE_ARRAY_OPT(ZMQ_SOCKS_PASSWORD, socks_password); -#endif -#ifdef ZMQ_SOCKS_PROXY -ZMQ_DEFINE_ARRAY_OPT(ZMQ_SOCKS_PROXY, socks_proxy); -#endif -#ifdef ZMQ_SOCKS_USERNAME -ZMQ_DEFINE_ARRAY_OPT(ZMQ_SOCKS_USERNAME, socks_username); -#endif -#ifdef ZMQ_STREAM_NOTIFY -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_STREAM_NOTIFY, stream_notify, int); -#endif -#ifdef ZMQ_SUBSCRIBE -ZMQ_DEFINE_ARRAY_OPT(ZMQ_SUBSCRIBE, subscribe); -#endif -#ifdef ZMQ_TCP_KEEPALIVE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE, tcp_keepalive, int); -#endif -#ifdef ZMQ_TCP_KEEPALIVE_CNT -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE_CNT, tcp_keepalive_cnt, int); -#endif -#ifdef ZMQ_TCP_KEEPALIVE_IDLE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE_IDLE, tcp_keepalive_idle, int); -#endif -#ifdef ZMQ_TCP_KEEPALIVE_INTVL -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE_INTVL, tcp_keepalive_intvl, int); -#endif -#ifdef ZMQ_TCP_MAXRT -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_MAXRT, tcp_maxrt, int); -#endif -#ifdef ZMQ_THREAD_SAFE -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_THREAD_SAFE, thread_safe, int); -#endif -#ifdef ZMQ_TOS -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TOS, tos, int); -#endif -#ifdef ZMQ_TYPE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TYPE, type, int); -#ifdef ZMQ_CPP11 -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TYPE, socket_type, socket_type); -#endif // ZMQ_CPP11 -#endif // ZMQ_TYPE -#ifdef ZMQ_UNSUBSCRIBE -ZMQ_DEFINE_ARRAY_OPT(ZMQ_UNSUBSCRIBE, unsubscribe); -#endif -#ifdef ZMQ_VMCI_BUFFER_SIZE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_BUFFER_SIZE, vmci_buffer_size, uint64_t); -#endif -#ifdef ZMQ_VMCI_BUFFER_MIN_SIZE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_BUFFER_MIN_SIZE, vmci_buffer_min_size, uint64_t); -#endif -#ifdef ZMQ_VMCI_BUFFER_MAX_SIZE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_BUFFER_MAX_SIZE, vmci_buffer_max_size, uint64_t); -#endif -#ifdef ZMQ_VMCI_CONNECT_TIMEOUT -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_CONNECT_TIMEOUT, vmci_connect_timeout, int); -#endif -#ifdef ZMQ_XPUB_VERBOSE -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_VERBOSE, xpub_verbose, int); -#endif -#ifdef ZMQ_XPUB_VERBOSER -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_VERBOSER, xpub_verboser, int); -#endif -#ifdef ZMQ_XPUB_MANUAL -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_MANUAL, xpub_manual, int); -#endif -#ifdef ZMQ_XPUB_MANUAL_LAST_VALUE -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_MANUAL_LAST_VALUE, xpub_manual_last_value, int); -#endif -#ifdef ZMQ_XPUB_NODROP -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_NODROP, xpub_nodrop, int); -#endif -#ifdef ZMQ_XPUB_WELCOME_MSG -ZMQ_DEFINE_ARRAY_OPT(ZMQ_XPUB_WELCOME_MSG, xpub_welcome_msg); -#endif -#ifdef ZMQ_ZAP_ENFORCE_DOMAIN -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ZAP_ENFORCE_DOMAIN, zap_enforce_domain, int); -#endif -#ifdef ZMQ_ZAP_DOMAIN -ZMQ_DEFINE_ARRAY_OPT(ZMQ_ZAP_DOMAIN, zap_domain); -#endif - -} // namespace sockopt -#endif // ZMQ_CPP11 - - -namespace detail -{ -class socket_base -{ - public: - socket_base() ZMQ_NOTHROW : _handle(ZMQ_NULLPTR) {} - ZMQ_EXPLICIT socket_base(void *handle) ZMQ_NOTHROW : _handle(handle) {} - - template - ZMQ_CPP11_DEPRECATED("from 4.7.0, use `set` taking option from zmq::sockopt") - void setsockopt(int option_, T const &optval) - { - setsockopt(option_, &optval, sizeof(T)); - } - - ZMQ_CPP11_DEPRECATED("from 4.7.0, use `set` taking option from zmq::sockopt") - void setsockopt(int option_, const void *optval_, size_t optvallen_) - { - int rc = zmq_setsockopt(_handle, option_, optval_, optvallen_); - if (rc != 0) - throw error_t(); - } - - ZMQ_CPP11_DEPRECATED("from 4.7.0, use `get` taking option from zmq::sockopt") - void getsockopt(int option_, void *optval_, size_t *optvallen_) const - { - int rc = zmq_getsockopt(_handle, option_, optval_, optvallen_); - if (rc != 0) - throw error_t(); - } - - template - ZMQ_CPP11_DEPRECATED("from 4.7.0, use `get` taking option from zmq::sockopt") - T getsockopt(int option_) const - { - T optval; - size_t optlen = sizeof(T); - getsockopt(option_, &optval, &optlen); - return optval; - } - -#ifdef ZMQ_CPP11 - // Set integral socket option, e.g. - // `socket.set(zmq::sockopt::linger, 0)` - template - void set(sockopt::integral_option, const T &val) - { - static_assert(std::is_integral::value, "T must be integral"); - set_option(Opt, &val, sizeof val); - } - - // Set integral socket option from boolean, e.g. - // `socket.set(zmq::sockopt::immediate, false)` - template - void set(sockopt::integral_option, bool val) - { - static_assert(std::is_integral::value, "T must be integral"); - T rep_val = val; - set_option(Opt, &rep_val, sizeof rep_val); - } - - // Set array socket option, e.g. - // `socket.set(zmq::sockopt::plain_username, "foo123")` - template - void set(sockopt::array_option, const char *buf) - { - set_option(Opt, buf, std::strlen(buf)); - } - - // Set array socket option, e.g. - // `socket.set(zmq::sockopt::routing_id, zmq::buffer(id))` - template - void set(sockopt::array_option, const_buffer buf) - { - set_option(Opt, buf.data(), buf.size()); - } - - // Set array socket option, e.g. - // `socket.set(zmq::sockopt::routing_id, id_str)` - template - void set(sockopt::array_option, const std::string &buf) - { - set_option(Opt, buf.data(), buf.size()); - } - -#if CPPZMQ_HAS_STRING_VIEW - // Set array socket option, e.g. - // `socket.set(zmq::sockopt::routing_id, id_str)` - template - void set(sockopt::array_option, std::string_view buf) - { - set_option(Opt, buf.data(), buf.size()); - } -#endif - - // Get scalar socket option, e.g. - // `auto opt = socket.get(zmq::sockopt::linger)` - template - ZMQ_NODISCARD T get(sockopt::integral_option) const - { - static_assert(std::is_scalar::value, "T must be scalar"); - T val; - size_t size = sizeof val; - get_option(Opt, &val, &size); - assert(size == sizeof val); - return val; - } - - // Get array socket option, writes to buf, returns option size in bytes, e.g. - // `size_t optsize = socket.get(zmq::sockopt::routing_id, zmq::buffer(id))` - template - ZMQ_NODISCARD size_t get(sockopt::array_option, - mutable_buffer buf) const - { - size_t size = buf.size(); - get_option(Opt, buf.data(), &size); - return size; - } - - // Get array socket option as string (initializes the string buffer size to init_size) e.g. - // `auto s = socket.get(zmq::sockopt::routing_id)` - // Note: removes the null character from null-terminated string options, - // i.e. the string size excludes the null character. - template - ZMQ_NODISCARD std::string get(sockopt::array_option, - size_t init_size = 1024) const - { - if ZMQ_CONSTEXPR_IF (NullTerm == 2) { - if (init_size == 1024) { - init_size = 41; // get as Z85 string - } - } - std::string str(init_size, '\0'); - size_t size = get(sockopt::array_option{}, buffer(str)); - if ZMQ_CONSTEXPR_IF (NullTerm == 1) { - if (size > 0) { - assert(str[size - 1] == '\0'); - --size; - } - } else if ZMQ_CONSTEXPR_IF (NullTerm == 2) { - assert(size == 32 || size == 41); - if (size == 41) { - assert(str[size - 1] == '\0'); - --size; - } - } - str.resize(size); - return str; - } -#endif - - void bind(std::string const &addr) { bind(addr.c_str()); } - - void bind(const char *addr_) - { - int rc = zmq_bind(_handle, addr_); - if (rc != 0) - throw error_t(); - } - - void unbind(std::string const &addr) { unbind(addr.c_str()); } - - void unbind(const char *addr_) - { - int rc = zmq_unbind(_handle, addr_); - if (rc != 0) - throw error_t(); - } - - void connect(std::string const &addr) { connect(addr.c_str()); } - - void connect(const char *addr_) - { - int rc = zmq_connect(_handle, addr_); - if (rc != 0) - throw error_t(); - } - - void disconnect(std::string const &addr) { disconnect(addr.c_str()); } - - void disconnect(const char *addr_) - { - int rc = zmq_disconnect(_handle, addr_); - if (rc != 0) - throw error_t(); - } - - ZMQ_DEPRECATED("from 4.7.1, use handle() != nullptr or operator bool") - bool connected() const ZMQ_NOTHROW { return (_handle != ZMQ_NULLPTR); } - - ZMQ_CPP11_DEPRECATED("from 4.3.1, use send taking a const_buffer and send_flags") - size_t send(const void *buf_, size_t len_, int flags_ = 0) - { - int nbytes = zmq_send(_handle, buf_, len_, flags_); - if (nbytes >= 0) - return static_cast(nbytes); - if (zmq_errno() == EAGAIN) - return 0; - throw error_t(); - } - - ZMQ_CPP11_DEPRECATED("from 4.3.1, use send taking message_t and send_flags") - bool send(message_t &msg_, - int flags_ = 0) // default until removed - { - int nbytes = zmq_msg_send(msg_.handle(), _handle, flags_); - if (nbytes >= 0) - return true; - if (zmq_errno() == EAGAIN) - return false; - throw error_t(); - } - - template - ZMQ_CPP11_DEPRECATED( - "from 4.4.1, use send taking message_t or buffer (for contiguous " - "ranges), and send_flags") - bool send(T first, T last, int flags_ = 0) - { - zmq::message_t msg(first, last); - int nbytes = zmq_msg_send(msg.handle(), _handle, flags_); - if (nbytes >= 0) - return true; - if (zmq_errno() == EAGAIN) - return false; - throw error_t(); - } - -#ifdef ZMQ_HAS_RVALUE_REFS - ZMQ_CPP11_DEPRECATED("from 4.3.1, use send taking message_t and send_flags") - bool send(message_t &&msg_, - int flags_ = 0) // default until removed - { -#ifdef ZMQ_CPP11 - return send(msg_, static_cast(flags_)).has_value(); -#else - return send(msg_, flags_); -#endif - } -#endif - -#ifdef ZMQ_CPP11 - send_result_t send(const_buffer buf, send_flags flags = send_flags::none) - { - const int nbytes = - zmq_send(_handle, buf.data(), buf.size(), static_cast(flags)); - if (nbytes >= 0) - return static_cast(nbytes); - if (zmq_errno() == EAGAIN) - return {}; - throw error_t(); - } - - send_result_t send(message_t &msg, send_flags flags) - { - int nbytes = zmq_msg_send(msg.handle(), _handle, static_cast(flags)); - if (nbytes >= 0) - return static_cast(nbytes); - if (zmq_errno() == EAGAIN) - return {}; - throw error_t(); - } - - send_result_t send(message_t &&msg, send_flags flags) - { - return send(msg, flags); - } -#endif - - ZMQ_CPP11_DEPRECATED( - "from 4.3.1, use recv taking a mutable_buffer and recv_flags") - size_t recv(void *buf_, size_t len_, int flags_ = 0) - { - int nbytes = zmq_recv(_handle, buf_, len_, flags_); - if (nbytes >= 0) - return static_cast(nbytes); - if (zmq_errno() == EAGAIN) - return 0; - throw error_t(); - } - - ZMQ_CPP11_DEPRECATED( - "from 4.3.1, use recv taking a reference to message_t and recv_flags") - bool recv(message_t *msg_, int flags_ = 0) - { - int nbytes = zmq_msg_recv(msg_->handle(), _handle, flags_); - if (nbytes >= 0) - return true; - if (zmq_errno() == EAGAIN) - return false; - throw error_t(); - } - -#ifdef ZMQ_CPP11 - ZMQ_NODISCARD - recv_buffer_result_t recv(mutable_buffer buf, - recv_flags flags = recv_flags::none) - { - const int nbytes = - zmq_recv(_handle, buf.data(), buf.size(), static_cast(flags)); - if (nbytes >= 0) { - return recv_buffer_size{ - (std::min)(static_cast(nbytes), buf.size()), - static_cast(nbytes)}; - } - if (zmq_errno() == EAGAIN) - return {}; - throw error_t(); - } - - ZMQ_NODISCARD - recv_result_t recv(message_t &msg, recv_flags flags = recv_flags::none) - { - const int nbytes = - zmq_msg_recv(msg.handle(), _handle, static_cast(flags)); - if (nbytes >= 0) { - assert(msg.size() == static_cast(nbytes)); - return static_cast(nbytes); - } - if (zmq_errno() == EAGAIN) - return {}; - throw error_t(); - } -#endif - -#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0) - void join(const char *group) - { - int rc = zmq_join(_handle, group); - if (rc != 0) - throw error_t(); - } - - void leave(const char *group) - { - int rc = zmq_leave(_handle, group); - if (rc != 0) - throw error_t(); - } -#endif - - ZMQ_NODISCARD void *handle() ZMQ_NOTHROW { return _handle; } - ZMQ_NODISCARD const void *handle() const ZMQ_NOTHROW { return _handle; } - - ZMQ_EXPLICIT operator bool() const ZMQ_NOTHROW { return _handle != ZMQ_NULLPTR; } - // note: non-const operator bool can be removed once - // operator void* is removed from socket_t - ZMQ_EXPLICIT operator bool() ZMQ_NOTHROW { return _handle != ZMQ_NULLPTR; } - - protected: - void *_handle; - - private: - void set_option(int option_, const void *optval_, size_t optvallen_) - { - int rc = zmq_setsockopt(_handle, option_, optval_, optvallen_); - if (rc != 0) - throw error_t(); - } - - void get_option(int option_, void *optval_, size_t *optvallen_) const - { - int rc = zmq_getsockopt(_handle, option_, optval_, optvallen_); - if (rc != 0) - throw error_t(); - } -}; -} // namespace detail - -struct from_handle_t -{ - struct _private - { - }; // disabling use other than with from_handle - ZMQ_CONSTEXPR_FN ZMQ_EXPLICIT from_handle_t(_private /*p*/) ZMQ_NOTHROW {} -}; - -ZMQ_CONSTEXPR_VAR from_handle_t from_handle = - from_handle_t(from_handle_t::_private()); - -// A non-owning nullable reference to a socket. -// The reference is invalidated on socket close or destruction. -class socket_ref : public detail::socket_base -{ - public: - socket_ref() ZMQ_NOTHROW : detail::socket_base() {} -#ifdef ZMQ_CPP11 - socket_ref(std::nullptr_t) ZMQ_NOTHROW : detail::socket_base() {} -#endif - socket_ref(from_handle_t /*fh*/, void *handle) ZMQ_NOTHROW - : detail::socket_base(handle) - { - } -}; - -#ifdef ZMQ_CPP11 -inline bool operator==(socket_ref sr, std::nullptr_t /*p*/) ZMQ_NOTHROW -{ - return sr.handle() == nullptr; -} -inline bool operator==(std::nullptr_t /*p*/, socket_ref sr) ZMQ_NOTHROW -{ - return sr.handle() == nullptr; -} -inline bool operator!=(socket_ref sr, std::nullptr_t /*p*/) ZMQ_NOTHROW -{ - return !(sr == nullptr); -} -inline bool operator!=(std::nullptr_t /*p*/, socket_ref sr) ZMQ_NOTHROW -{ - return !(sr == nullptr); -} -#endif - -inline bool operator==(const detail::socket_base& a, const detail::socket_base& b) ZMQ_NOTHROW -{ - return std::equal_to()(a.handle(), b.handle()); -} -inline bool operator!=(const detail::socket_base& a, const detail::socket_base& b) ZMQ_NOTHROW -{ - return !(a == b); -} -inline bool operator<(const detail::socket_base& a, const detail::socket_base& b) ZMQ_NOTHROW -{ - return std::less()(a.handle(), b.handle()); -} -inline bool operator>(const detail::socket_base& a, const detail::socket_base& b) ZMQ_NOTHROW -{ - return b < a; -} -inline bool operator<=(const detail::socket_base& a, const detail::socket_base& b) ZMQ_NOTHROW -{ - return !(a > b); -} -inline bool operator>=(const detail::socket_base& a, const detail::socket_base& b) ZMQ_NOTHROW -{ - return !(a < b); -} - -} // namespace zmq - -#ifdef ZMQ_CPP11 -namespace std -{ -template<> struct hash -{ - size_t operator()(zmq::socket_ref sr) const ZMQ_NOTHROW - { - return hash()(sr.handle()); - } -}; -} // namespace std -#endif - -namespace zmq -{ -class socket_t : public detail::socket_base -{ - friend class monitor_t; - - public: - socket_t() ZMQ_NOTHROW : detail::socket_base(ZMQ_NULLPTR), ctxptr(ZMQ_NULLPTR) {} - - socket_t(context_t &context_, int type_) : - detail::socket_base(zmq_socket(context_.handle(), type_)), - ctxptr(context_.handle()) - { - if (_handle == ZMQ_NULLPTR) - throw error_t(); - } - -#ifdef ZMQ_CPP11 - socket_t(context_t &context_, socket_type type_) : - socket_t(context_, static_cast(type_)) - { - } -#endif - -#ifdef ZMQ_HAS_RVALUE_REFS - socket_t(socket_t &&rhs) ZMQ_NOTHROW : detail::socket_base(rhs._handle), - ctxptr(rhs.ctxptr) - { - rhs._handle = ZMQ_NULLPTR; - rhs.ctxptr = ZMQ_NULLPTR; - } - socket_t &operator=(socket_t &&rhs) ZMQ_NOTHROW - { - close(); - std::swap(_handle, rhs._handle); - std::swap(ctxptr, rhs.ctxptr); - return *this; - } -#endif - - ~socket_t() ZMQ_NOTHROW { close(); } - - operator void *() ZMQ_NOTHROW { return _handle; } - - operator void const *() const ZMQ_NOTHROW { return _handle; } - - void close() ZMQ_NOTHROW - { - if (_handle == ZMQ_NULLPTR) - // already closed - return; - int rc = zmq_close(_handle); - ZMQ_ASSERT(rc == 0); - _handle = ZMQ_NULLPTR; - ctxptr = ZMQ_NULLPTR; - } - - void swap(socket_t &other) ZMQ_NOTHROW - { - std::swap(_handle, other._handle); - std::swap(ctxptr, other.ctxptr); - } - - operator socket_ref() ZMQ_NOTHROW { return socket_ref(from_handle, _handle); } - - private: - void *ctxptr; - - socket_t(const socket_t &) ZMQ_DELETED_FUNCTION; - void operator=(const socket_t &) ZMQ_DELETED_FUNCTION; - - // used by monitor_t - socket_t(void *context_, int type_) : - detail::socket_base(zmq_socket(context_, type_)), ctxptr(context_) - { - if (_handle == ZMQ_NULLPTR) - throw error_t(); - if (ctxptr == ZMQ_NULLPTR) - throw error_t(); - } -}; - -inline void swap(socket_t &a, socket_t &b) ZMQ_NOTHROW -{ - a.swap(b); -} - -ZMQ_DEPRECATED("from 4.3.1, use proxy taking socket_t objects") -inline void proxy(void *frontend, void *backend, void *capture) -{ - int rc = zmq_proxy(frontend, backend, capture); - if (rc != 0) - throw error_t(); -} - -inline void -proxy(socket_ref frontend, socket_ref backend, socket_ref capture = socket_ref()) -{ - int rc = zmq_proxy(frontend.handle(), backend.handle(), capture.handle()); - if (rc != 0) - throw error_t(); -} - -#ifdef ZMQ_HAS_PROXY_STEERABLE -ZMQ_DEPRECATED("from 4.3.1, use proxy_steerable taking socket_t objects") -inline void -proxy_steerable(void *frontend, void *backend, void *capture, void *control) -{ - int rc = zmq_proxy_steerable(frontend, backend, capture, control); - if (rc != 0) - throw error_t(); -} - -inline void proxy_steerable(socket_ref frontend, - socket_ref backend, - socket_ref capture, - socket_ref control) -{ - int rc = zmq_proxy_steerable(frontend.handle(), backend.handle(), - capture.handle(), control.handle()); - if (rc != 0) - throw error_t(); -} -#endif - -class monitor_t -{ - public: - monitor_t() : _socket(), _monitor_socket() {} - - virtual ~monitor_t() { close(); } - -#ifdef ZMQ_HAS_RVALUE_REFS - monitor_t(monitor_t &&rhs) ZMQ_NOTHROW : _socket(), _monitor_socket() - { - std::swap(_socket, rhs._socket); - std::swap(_monitor_socket, rhs._monitor_socket); - } - - monitor_t &operator=(monitor_t &&rhs) ZMQ_NOTHROW - { - close(); - _socket = socket_ref(); - std::swap(_socket, rhs._socket); - std::swap(_monitor_socket, rhs._monitor_socket); - return *this; - } -#endif - - - void - monitor(socket_t &socket, std::string const &addr, int events = ZMQ_EVENT_ALL) - { - monitor(socket, addr.c_str(), events); - } - - void monitor(socket_t &socket, const char *addr_, int events = ZMQ_EVENT_ALL) - { - init(socket, addr_, events); - while (true) { - check_event(-1); - } - } - - void init(socket_t &socket, std::string const &addr, int events = ZMQ_EVENT_ALL) - { - init(socket, addr.c_str(), events); - } - - void init(socket_t &socket, const char *addr_, int events = ZMQ_EVENT_ALL) - { - int rc = zmq_socket_monitor(socket.handle(), addr_, events); - if (rc != 0) - throw error_t(); - - _socket = socket; - _monitor_socket = socket_t(socket.ctxptr, ZMQ_PAIR); - _monitor_socket.connect(addr_); - - on_monitor_started(); - } - - bool check_event(int timeout = 0) - { - assert(_monitor_socket); - - zmq::pollitem_t items[] = { - {_monitor_socket.handle(), 0, ZMQ_POLLIN, 0}, - }; - - #ifdef ZMQ_CPP11 - zmq::poll(&items[0], 1, std::chrono::milliseconds(timeout)); - #else - zmq::poll(&items[0], 1, timeout); - #endif - - return process_event(items[0].revents); - } - -#ifdef ZMQ_EVENT_MONITOR_STOPPED - void abort() - { - if (_socket) - zmq_socket_monitor(_socket.handle(), ZMQ_NULLPTR, 0); - - _socket = socket_ref(); - } - - virtual void on_monitor_stopped() {} -#endif - virtual void on_monitor_started() {} - virtual void on_event_connected(const zmq_event_t &event_, const char *addr_) - { - (void) event_; - (void) addr_; - } - virtual void on_event_connect_delayed(const zmq_event_t &event_, - const char *addr_) - { - (void) event_; - (void) addr_; - } - virtual void on_event_connect_retried(const zmq_event_t &event_, - const char *addr_) - { - (void) event_; - (void) addr_; - } - virtual void on_event_listening(const zmq_event_t &event_, const char *addr_) - { - (void) event_; - (void) addr_; - } - virtual void on_event_bind_failed(const zmq_event_t &event_, const char *addr_) - { - (void) event_; - (void) addr_; - } - virtual void on_event_accepted(const zmq_event_t &event_, const char *addr_) - { - (void) event_; - (void) addr_; - } - virtual void on_event_accept_failed(const zmq_event_t &event_, const char *addr_) - { - (void) event_; - (void) addr_; - } - virtual void on_event_closed(const zmq_event_t &event_, const char *addr_) - { - (void) event_; - (void) addr_; - } - virtual void on_event_close_failed(const zmq_event_t &event_, const char *addr_) - { - (void) event_; - (void) addr_; - } - virtual void on_event_disconnected(const zmq_event_t &event_, const char *addr_) - { - (void) event_; - (void) addr_; - } -#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3) - virtual void on_event_handshake_failed_no_detail(const zmq_event_t &event_, - const char *addr_) - { - (void) event_; - (void) addr_; - } - virtual void on_event_handshake_failed_protocol(const zmq_event_t &event_, - const char *addr_) - { - (void) event_; - (void) addr_; - } - virtual void on_event_handshake_failed_auth(const zmq_event_t &event_, - const char *addr_) - { - (void) event_; - (void) addr_; - } - virtual void on_event_handshake_succeeded(const zmq_event_t &event_, - const char *addr_) - { - (void) event_; - (void) addr_; - } -#elif ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 1) - virtual void on_event_handshake_failed(const zmq_event_t &event_, - const char *addr_) - { - (void) event_; - (void) addr_; - } - virtual void on_event_handshake_succeed(const zmq_event_t &event_, - const char *addr_) - { - (void) event_; - (void) addr_; - } -#endif - virtual void on_event_unknown(const zmq_event_t &event_, const char *addr_) - { - (void) event_; - (void) addr_; - } - - protected: - bool process_event(short events) - { - zmq::message_t eventMsg; - - if (events & ZMQ_POLLIN) { - int rc = zmq_msg_recv(eventMsg.handle(), _monitor_socket.handle(), 0); - if (rc == -1 && zmq_errno() == ETERM) - return false; - assert(rc != -1); - - } else { - return false; - } - -#if ZMQ_VERSION_MAJOR >= 4 - const char *data = static_cast(eventMsg.data()); - zmq_event_t msgEvent; - memcpy(&msgEvent.event, data, sizeof(uint16_t)); - data += sizeof(uint16_t); - memcpy(&msgEvent.value, data, sizeof(int32_t)); - zmq_event_t *event = &msgEvent; -#else - zmq_event_t *event = static_cast(eventMsg.data()); -#endif - -#ifdef ZMQ_NEW_MONITOR_EVENT_LAYOUT - zmq::message_t addrMsg; - int rc = zmq_msg_recv(addrMsg.handle(), _monitor_socket.handle(), 0); - if (rc == -1 && zmq_errno() == ETERM) { - return false; - } - - assert(rc != -1); - std::string address = addrMsg.to_string(); -#else - // Bit of a hack, but all events in the zmq_event_t union have the same layout so this will work for all event types. - std::string address = event->data.connected.addr; -#endif - -#ifdef ZMQ_EVENT_MONITOR_STOPPED - if (event->event == ZMQ_EVENT_MONITOR_STOPPED) { - on_monitor_stopped(); - return false; - } - -#endif - - switch (event->event) { - case ZMQ_EVENT_CONNECTED: - on_event_connected(*event, address.c_str()); - break; - case ZMQ_EVENT_CONNECT_DELAYED: - on_event_connect_delayed(*event, address.c_str()); - break; - case ZMQ_EVENT_CONNECT_RETRIED: - on_event_connect_retried(*event, address.c_str()); - break; - case ZMQ_EVENT_LISTENING: - on_event_listening(*event, address.c_str()); - break; - case ZMQ_EVENT_BIND_FAILED: - on_event_bind_failed(*event, address.c_str()); - break; - case ZMQ_EVENT_ACCEPTED: - on_event_accepted(*event, address.c_str()); - break; - case ZMQ_EVENT_ACCEPT_FAILED: - on_event_accept_failed(*event, address.c_str()); - break; - case ZMQ_EVENT_CLOSED: - on_event_closed(*event, address.c_str()); - break; - case ZMQ_EVENT_CLOSE_FAILED: - on_event_close_failed(*event, address.c_str()); - break; - case ZMQ_EVENT_DISCONNECTED: - on_event_disconnected(*event, address.c_str()); - break; -#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 3, 0) || (defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3)) - case ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL: - on_event_handshake_failed_no_detail(*event, address.c_str()); - break; - case ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL: - on_event_handshake_failed_protocol(*event, address.c_str()); - break; - case ZMQ_EVENT_HANDSHAKE_FAILED_AUTH: - on_event_handshake_failed_auth(*event, address.c_str()); - break; - case ZMQ_EVENT_HANDSHAKE_SUCCEEDED: - on_event_handshake_succeeded(*event, address.c_str()); - break; -#elif defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 1) - case ZMQ_EVENT_HANDSHAKE_FAILED: - on_event_handshake_failed(*event, address.c_str()); - break; - case ZMQ_EVENT_HANDSHAKE_SUCCEED: - on_event_handshake_succeed(*event, address.c_str()); - break; -#endif - default: - on_event_unknown(*event, address.c_str()); - break; - } - - return true; - } - - socket_ref monitor_socket() {return _monitor_socket;} - - private: - monitor_t(const monitor_t &) ZMQ_DELETED_FUNCTION; - void operator=(const monitor_t &) ZMQ_DELETED_FUNCTION; - - socket_ref _socket; - socket_t _monitor_socket; - - void close() ZMQ_NOTHROW - { - if (_socket) - zmq_socket_monitor(_socket.handle(), ZMQ_NULLPTR, 0); - _monitor_socket.close(); - } -}; - -#if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER) - -// polling events -enum class event_flags : short -{ - none = 0, - pollin = ZMQ_POLLIN, - pollout = ZMQ_POLLOUT, - pollerr = ZMQ_POLLERR, - pollpri = ZMQ_POLLPRI -}; - -constexpr event_flags operator|(event_flags a, event_flags b) noexcept -{ - return detail::enum_bit_or(a, b); -} -constexpr event_flags operator&(event_flags a, event_flags b) noexcept -{ - return detail::enum_bit_and(a, b); -} -constexpr event_flags operator^(event_flags a, event_flags b) noexcept -{ - return detail::enum_bit_xor(a, b); -} -constexpr event_flags operator~(event_flags a) noexcept -{ - return detail::enum_bit_not(a); -} - -struct no_user_data; - -// layout compatible with zmq_poller_event_t -template struct poller_event -{ - socket_ref socket; - ::zmq::fd_t fd; - T *user_data; - event_flags events; -}; - -template class poller_t -{ - public: - using event_type = poller_event; - - poller_t() : poller_ptr(zmq_poller_new()) - { - if (!poller_ptr) - throw error_t(); - } - - template< - typename Dummy = void, - typename = - typename std::enable_if::value, Dummy>::type> - void add(zmq::socket_ref socket, event_flags events, T *user_data) - { - add_impl(socket, events, user_data); - } - - void add(zmq::socket_ref socket, event_flags events) - { - add_impl(socket, events, nullptr); - } - - template< - typename Dummy = void, - typename = - typename std::enable_if::value, Dummy>::type> - void add(fd_t fd, event_flags events, T *user_data) - { - add_impl(fd, events, user_data); - } - - void add(fd_t fd, event_flags events) { add_impl(fd, events, nullptr); } - - void remove(zmq::socket_ref socket) - { - if (0 != zmq_poller_remove(poller_ptr.get(), socket.handle())) { - throw error_t(); - } - } - - void remove(fd_t fd) - { - if (0 != zmq_poller_remove_fd(poller_ptr.get(), fd)) { - throw error_t(); - } - } - - void modify(zmq::socket_ref socket, event_flags events) - { - if (0 - != zmq_poller_modify(poller_ptr.get(), socket.handle(), - static_cast(events))) { - throw error_t(); - } - } - - void modify(fd_t fd, event_flags events) - { - if (0 - != zmq_poller_modify_fd(poller_ptr.get(), fd, - static_cast(events))) { - throw error_t(); - } - } - - template - size_t wait_all(Sequence &poller_events, - const std::chrono::milliseconds timeout) - { - static_assert(std::is_same::value, - "Sequence::value_type must be of poller_t::event_type"); - int rc = zmq_poller_wait_all( - poller_ptr.get(), - reinterpret_cast(poller_events.data()), - static_cast(poller_events.size()), - static_cast(timeout.count())); - if (rc > 0) - return static_cast(rc); - -#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3) - if (zmq_errno() == EAGAIN) -#else - if (zmq_errno() == ETIMEDOUT) -#endif - return 0; - - throw error_t(); - } - -#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 3, 3) - size_t size() const noexcept - { - int rc = zmq_poller_size(const_cast(poller_ptr.get())); - ZMQ_ASSERT(rc >= 0); - return static_cast((std::max)(rc, 0)); - } -#endif - - private: - struct destroy_poller_t - { - void operator()(void *ptr) noexcept - { - int rc = zmq_poller_destroy(&ptr); - ZMQ_ASSERT(rc == 0); - } - }; - - std::unique_ptr poller_ptr; - - void add_impl(zmq::socket_ref socket, event_flags events, T *user_data) - { - if (0 - != zmq_poller_add(poller_ptr.get(), socket.handle(), user_data, - static_cast(events))) { - throw error_t(); - } - } - - void add_impl(fd_t fd, event_flags events, T *user_data) - { - if (0 - != zmq_poller_add_fd(poller_ptr.get(), fd, user_data, - static_cast(events))) { - throw error_t(); - } - } -}; -#endif // defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER) - -inline std::ostream &operator<<(std::ostream &os, const message_t &msg) -{ - return os << msg.str(); -} - -#if defined(ZMQ_CPP11) && defined(ZMQ_HAVE_TIMERS) - -class timers -{ - public: - using id_t = int; - using fn_t = zmq_timer_fn; - -#if CPPZMQ_HAS_OPTIONAL - using timeout_result_t = std::optional; -#else - using timeout_result_t = detail::trivial_optional; -#endif - - timers() : _timers(zmq_timers_new()) - { - if (_timers == nullptr) - throw error_t(); - } - - timers(const timers &other) = delete; - timers &operator=(const timers &other) = delete; - - ~timers() - { - int rc = zmq_timers_destroy(&_timers); - ZMQ_ASSERT(rc == 0); - } - - id_t add(std::chrono::milliseconds interval, zmq_timer_fn handler, void *arg) - { - id_t timer_id = zmq_timers_add(_timers, interval.count(), handler, arg); - if (timer_id == -1) - throw zmq::error_t(); - return timer_id; - } - - void cancel(id_t timer_id) - { - int rc = zmq_timers_cancel(_timers, timer_id); - if (rc == -1) - throw zmq::error_t(); - } - - void set_interval(id_t timer_id, std::chrono::milliseconds interval) - { - int rc = zmq_timers_set_interval(_timers, timer_id, interval.count()); - if (rc == -1) - throw zmq::error_t(); - } - - void reset(id_t timer_id) - { - int rc = zmq_timers_reset(_timers, timer_id); - if (rc == -1) - throw zmq::error_t(); - } - - timeout_result_t timeout() const - { - int timeout = zmq_timers_timeout(_timers); - if (timeout == -1) - return timeout_result_t{}; - return std::chrono::milliseconds{timeout}; - } - - void execute() - { - int rc = zmq_timers_execute(_timers); - if (rc == -1) - throw zmq::error_t(); - } - - private: - void *_timers; -}; - -#endif // defined(ZMQ_CPP11) && defined(ZMQ_HAVE_TIMERS) - -} // namespace zmq - -#endif // __ZMQ_HPP_INCLUDED__ diff --git a/3rdparty/cppzmq/zmq_addon.hpp b/3rdparty/cppzmq/zmq_addon.hpp deleted file mode 100644 index c6b4462cb..000000000 --- a/3rdparty/cppzmq/zmq_addon.hpp +++ /dev/null @@ -1,848 +0,0 @@ -/* - Copyright (c) 2016-2017 ZeroMQ community - Copyright (c) 2016 VOCA AS / Harald Nøkland - - 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 __ZMQ_ADDON_HPP_INCLUDED__ -#define __ZMQ_ADDON_HPP_INCLUDED__ - -#include "zmq.hpp" - -#include -#include -#include -#include -#ifdef ZMQ_CPP11 -#include -#include -#include - -namespace zmq -{ - // socket ref or native file descriptor for poller - class poller_ref_t - { - public: - enum RefType - { - RT_SOCKET, - RT_FD - }; - - poller_ref_t() : poller_ref_t(socket_ref{}) - {} - - poller_ref_t(const zmq::socket_ref& socket) : data{RT_SOCKET, socket, {}} - {} - - poller_ref_t(zmq::fd_t fd) : data{RT_FD, {}, fd} - {} - - size_t hash() const ZMQ_NOTHROW - { - std::size_t h = 0; - hash_combine(h, std::get<0>(data)); - hash_combine(h, std::get<1>(data)); - hash_combine(h, std::get<2>(data)); - return h; - } - - bool operator == (const poller_ref_t& o) const ZMQ_NOTHROW - { - return data == o.data; - } - - private: - template - static void hash_combine(std::size_t& seed, const T& v) ZMQ_NOTHROW - { - std::hash hasher; - seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2); - } - - std::tuple data; - - }; // class poller_ref_t - -} // namespace zmq - -// std::hash<> specialization for std::unordered_map -template <> struct std::hash -{ - size_t operator()(const zmq::poller_ref_t& ref) const ZMQ_NOTHROW - { - return ref.hash(); - } -}; -#endif // ZMQ_CPP11 - -namespace zmq -{ -#ifdef ZMQ_CPP11 - -namespace detail -{ -template -recv_result_t -recv_multipart_n(socket_ref s, OutputIt out, size_t n, recv_flags flags) -{ - size_t msg_count = 0; - message_t msg; - while (true) { - if ZMQ_CONSTEXPR_IF (CheckN) { - if (msg_count >= n) - throw std::runtime_error( - "Too many message parts in recv_multipart_n"); - } - if (!s.recv(msg, flags)) { - // zmq ensures atomic delivery of messages - assert(msg_count == 0); - return {}; - } - ++msg_count; - const bool more = msg.more(); - *out++ = std::move(msg); - if (!more) - break; - } - return msg_count; -} - -inline bool is_little_endian() -{ - const uint16_t i = 0x01; - return *reinterpret_cast(&i) == 0x01; -} - -inline void write_network_order(unsigned char *buf, const uint32_t value) -{ - if (is_little_endian()) { - ZMQ_CONSTEXPR_VAR uint32_t mask = (std::numeric_limits::max)(); - *buf++ = static_cast((value >> 24) & mask); - *buf++ = static_cast((value >> 16) & mask); - *buf++ = static_cast((value >> 8) & mask); - *buf++ = static_cast(value & mask); - } else { - std::memcpy(buf, &value, sizeof(value)); - } -} - -inline uint32_t read_u32_network_order(const unsigned char *buf) -{ - if (is_little_endian()) { - return (static_cast(buf[0]) << 24) - + (static_cast(buf[1]) << 16) - + (static_cast(buf[2]) << 8) - + static_cast(buf[3]); - } else { - uint32_t value; - std::memcpy(&value, buf, sizeof(value)); - return value; - } -} -} // namespace detail - -/* Receive a multipart message. - - Writes the zmq::message_t objects to OutputIterator out. - The out iterator must handle an unspecified number of writes, - e.g. by using std::back_inserter. - - Returns: the number of messages received or nullopt (on EAGAIN). - Throws: if recv throws. Any exceptions thrown - by the out iterator will be propagated and the message - may have been only partially received with pending - message parts. It is adviced to close this socket in that event. -*/ -template -ZMQ_NODISCARD recv_result_t recv_multipart(socket_ref s, - OutputIt out, - recv_flags flags = recv_flags::none) -{ - return detail::recv_multipart_n(s, std::move(out), 0, flags); -} - -/* Receive a multipart message. - - Writes at most n zmq::message_t objects to OutputIterator out. - If the number of message parts of the incoming message exceeds n - then an exception will be thrown. - - Returns: the number of messages received or nullopt (on EAGAIN). - Throws: if recv throws. Throws std::runtime_error if the number - of message parts exceeds n (exactly n messages will have been written - to out). Any exceptions thrown - by the out iterator will be propagated and the message - may have been only partially received with pending - message parts. It is adviced to close this socket in that event. -*/ -template -ZMQ_NODISCARD recv_result_t recv_multipart_n(socket_ref s, - OutputIt out, - size_t n, - recv_flags flags = recv_flags::none) -{ - return detail::recv_multipart_n(s, std::move(out), n, flags); -} - -/* Send a multipart message. - - The range must be a ForwardRange of zmq::message_t, - zmq::const_buffer or zmq::mutable_buffer. - The flags may be zmq::send_flags::sndmore if there are - more message parts to be sent after the call to this function. - - Returns: the number of messages sent (exactly msgs.size()) or nullopt (on EAGAIN). - Throws: if send throws. Any exceptions thrown - by the msgs range will be propagated and the message - may have been only partially sent. It is adviced to close this socket in that event. -*/ -template::value - && (std::is_same, message_t>::value - || detail::is_buffer>::value)>::type -#endif - > -send_result_t -send_multipart(socket_ref s, Range &&msgs, send_flags flags = send_flags::none) -{ - using std::begin; - using std::end; - auto it = begin(msgs); - const auto end_it = end(msgs); - size_t msg_count = 0; - while (it != end_it) { - const auto next = std::next(it); - const auto msg_flags = - flags | (next == end_it ? send_flags::none : send_flags::sndmore); - if (!s.send(*it, msg_flags)) { - // zmq ensures atomic delivery of messages - assert(it == begin(msgs)); - return {}; - } - ++msg_count; - it = next; - } - return msg_count; -} - -/* Encode a multipart message. - - The range must be a ForwardRange of zmq::message_t. A - zmq::multipart_t or STL container may be passed for encoding. - - Returns: a zmq::message_t holding the encoded multipart data. - - Throws: std::range_error is thrown if the size of any single part - can not fit in an unsigned 32 bit integer. - - The encoding is compatible with that used by the CZMQ function - zmsg_encode(), see https://rfc.zeromq.org/spec/50/. - Each part consists of a size followed by the data. - These are placed contiguously into the output message. A part of - size less than 255 bytes will have a single byte size value. - Larger parts will have a five byte size value with the first byte - set to 0xFF and the remaining four bytes holding the size of the - part's data. -*/ -template::value - && (std::is_same, message_t>::value - || detail::is_buffer>::value)>::type -#endif - > -message_t encode(const Range &parts) -{ - size_t mmsg_size = 0; - - // First pass check sizes - for (const auto &part : parts) { - const size_t part_size = part.size(); - if (part_size > (std::numeric_limits::max)()) { - // Size value must fit into uint32_t. - throw std::range_error("Invalid size, message part too large"); - } - const size_t count_size = - part_size < (std::numeric_limits::max)() ? 1 : 5; - mmsg_size += part_size + count_size; - } - - message_t encoded(mmsg_size); - unsigned char *buf = encoded.data(); - for (const auto &part : parts) { - const uint32_t part_size = static_cast(part.size()); - const unsigned char *part_data = - static_cast(part.data()); - - if (part_size < (std::numeric_limits::max)()) { - // small part - *buf++ = static_cast(part_size); - } else { - // big part - *buf++ = (std::numeric_limits::max)(); - detail::write_network_order(buf, part_size); - buf += sizeof(part_size); - } - std::memcpy(buf, part_data, part_size); - buf += part_size; - } - - assert(static_cast(buf - encoded.data()) == mmsg_size); - return encoded; -} - -/* Decode an encoded message to multiple parts. - - The given output iterator must be a ForwardIterator to a container - holding zmq::message_t such as a zmq::multipart_t or various STL - containers. - - Returns the ForwardIterator advanced once past the last decoded - part. - - Throws: a std::out_of_range is thrown if the encoded part sizes - lead to exceeding the message data bounds. - - The decoding assumes the message is encoded in the manner - performed by zmq::encode(), see https://rfc.zeromq.org/spec/50/. - */ -template OutputIt decode(const message_t &encoded, OutputIt out) -{ - const unsigned char *source = encoded.data(); - const unsigned char *const limit = source + encoded.size(); - - while (source < limit) { - size_t part_size = *source++; - if (part_size == (std::numeric_limits::max)()) { - if (static_cast(limit - source) < sizeof(uint32_t)) { - throw std::out_of_range( - "Malformed encoding, overflow in reading size"); - } - part_size = detail::read_u32_network_order(source); - // the part size is allowed to be less than 0xFF - source += sizeof(uint32_t); - } - - if (static_cast(limit - source) < part_size) { - throw std::out_of_range("Malformed encoding, overflow in reading part"); - } - *out = message_t(source, part_size); - ++out; - source += part_size; - } - - assert(source == limit); - return out; -} - -#endif - - -#ifdef ZMQ_HAS_RVALUE_REFS - -/* - This class handles multipart messaging. It is the C++ equivalent of zmsg.h, - which is part of CZMQ (the high-level C binding). Furthermore, it is a major - improvement compared to zmsg.hpp, which is part of the examples in the ØMQ - Guide. Unnecessary copying is avoided by using move semantics to efficiently - add/remove parts. -*/ -class multipart_t -{ - private: - std::deque m_parts; - - public: - typedef std::deque::value_type value_type; - - typedef std::deque::iterator iterator; - typedef std::deque::const_iterator const_iterator; - - typedef std::deque::reverse_iterator reverse_iterator; - typedef std::deque::const_reverse_iterator const_reverse_iterator; - - // Default constructor - multipart_t() {} - - // Construct from socket receive - multipart_t(socket_ref socket) { recv(socket); } - - // Construct from memory block - multipart_t(const void *src, size_t size) { addmem(src, size); } - - // Construct from string - multipart_t(const std::string &string) { addstr(string); } - - // Construct from message part - multipart_t(message_t &&message) { add(std::move(message)); } - - // Move constructor - multipart_t(multipart_t &&other) ZMQ_NOTHROW { m_parts = std::move(other.m_parts); } - - // Move assignment operator - multipart_t &operator=(multipart_t &&other) ZMQ_NOTHROW - { - m_parts = std::move(other.m_parts); - return *this; - } - - // Destructor - virtual ~multipart_t() { clear(); } - - message_t &operator[](size_t n) { return m_parts[n]; } - - const message_t &operator[](size_t n) const { return m_parts[n]; } - - message_t &at(size_t n) { return m_parts.at(n); } - - const message_t &at(size_t n) const { return m_parts.at(n); } - - iterator begin() { return m_parts.begin(); } - - const_iterator begin() const { return m_parts.begin(); } - - const_iterator cbegin() const { return m_parts.cbegin(); } - - reverse_iterator rbegin() { return m_parts.rbegin(); } - - const_reverse_iterator rbegin() const { return m_parts.rbegin(); } - - iterator end() { return m_parts.end(); } - - const_iterator end() const { return m_parts.end(); } - - const_iterator cend() const { return m_parts.cend(); } - - reverse_iterator rend() { return m_parts.rend(); } - - const_reverse_iterator rend() const { return m_parts.rend(); } - - // Delete all parts - void clear() { m_parts.clear(); } - - // Get number of parts - size_t size() const { return m_parts.size(); } - - // Check if number of parts is zero - bool empty() const { return m_parts.empty(); } - - // Receive multipart message from socket - bool recv(socket_ref socket, int flags = 0) - { - clear(); - bool more = true; - while (more) { - message_t message; -#ifdef ZMQ_CPP11 - if (!socket.recv(message, static_cast(flags))) - return false; -#else - if (!socket.recv(&message, flags)) - return false; -#endif - more = message.more(); - add(std::move(message)); - } - return true; - } - - // Send multipart message to socket - bool send(socket_ref socket, int flags = 0) - { - flags &= ~(ZMQ_SNDMORE); - bool more = size() > 0; - while (more) { - message_t message = pop(); - more = size() > 0; -#ifdef ZMQ_CPP11 - if (!socket.send(message, static_cast( - (more ? ZMQ_SNDMORE : 0) | flags))) - return false; -#else - if (!socket.send(message, (more ? ZMQ_SNDMORE : 0) | flags)) - return false; -#endif - } - clear(); - return true; - } - - // Concatenate other multipart to front - void prepend(multipart_t &&other) - { - while (!other.empty()) - push(other.remove()); - } - - // Concatenate other multipart to back - void append(multipart_t &&other) - { - while (!other.empty()) - add(other.pop()); - } - - // Push memory block to front - void pushmem(const void *src, size_t size) - { - m_parts.push_front(message_t(src, size)); - } - - // Push memory block to back - void addmem(const void *src, size_t size) - { - m_parts.push_back(message_t(src, size)); - } - - // Push string to front - void pushstr(const std::string &string) - { - m_parts.push_front(message_t(string.data(), string.size())); - } - - // Push string to back - void addstr(const std::string &string) - { - m_parts.push_back(message_t(string.data(), string.size())); - } - - // Push type (fixed-size) to front - template void pushtyp(const T &type) - { - static_assert(!std::is_same::value, - "Use pushstr() instead of pushtyp()"); - m_parts.push_front(message_t(&type, sizeof(type))); - } - - // Push type (fixed-size) to back - template void addtyp(const T &type) - { - static_assert(!std::is_same::value, - "Use addstr() instead of addtyp()"); - m_parts.push_back(message_t(&type, sizeof(type))); - } - - // Push message part to front - void push(message_t &&message) { m_parts.push_front(std::move(message)); } - - // Push message part to back - void add(message_t &&message) { m_parts.push_back(std::move(message)); } - - // Alias to allow std::back_inserter() - void push_back(message_t &&message) { m_parts.push_back(std::move(message)); } - - // Pop string from front - std::string popstr() - { - std::string string(m_parts.front().data(), m_parts.front().size()); - m_parts.pop_front(); - return string; - } - - // Pop type (fixed-size) from front - template T poptyp() - { - static_assert(!std::is_same::value, - "Use popstr() instead of poptyp()"); - if (sizeof(T) != m_parts.front().size()) - throw std::runtime_error( - "Invalid type, size does not match the message size"); - T type = *m_parts.front().data(); - m_parts.pop_front(); - return type; - } - - // Pop message part from front - message_t pop() - { - message_t message = std::move(m_parts.front()); - m_parts.pop_front(); - return message; - } - - // Pop message part from back - message_t remove() - { - message_t message = std::move(m_parts.back()); - m_parts.pop_back(); - return message; - } - - // get message part from front - const message_t &front() { return m_parts.front(); } - - // get message part from back - const message_t &back() { return m_parts.back(); } - - // Get pointer to a specific message part - const message_t *peek(size_t index) const { return &m_parts[index]; } - - // Get a string copy of a specific message part - std::string peekstr(size_t index) const - { - std::string string(m_parts[index].data(), m_parts[index].size()); - return string; - } - - // Peek type (fixed-size) from front - template T peektyp(size_t index) const - { - static_assert(!std::is_same::value, - "Use peekstr() instead of peektyp()"); - if (sizeof(T) != m_parts[index].size()) - throw std::runtime_error( - "Invalid type, size does not match the message size"); - T type = *m_parts[index].data(); - return type; - } - - // Create multipart from type (fixed-size) - template static multipart_t create(const T &type) - { - multipart_t multipart; - multipart.addtyp(type); - return multipart; - } - - // Copy multipart - multipart_t clone() const - { - multipart_t multipart; - for (size_t i = 0; i < size(); i++) - multipart.addmem(m_parts[i].data(), m_parts[i].size()); - return multipart; - } - - // Dump content to string - std::string str() const - { - std::stringstream ss; - for (size_t i = 0; i < m_parts.size(); i++) { - const unsigned char *data = m_parts[i].data(); - size_t size = m_parts[i].size(); - - // Dump the message as text or binary - bool isText = true; - for (size_t j = 0; j < size; j++) { - if (data[j] < 32 || data[j] > 127) { - isText = false; - break; - } - } - ss << "\n[" << std::dec << std::setw(3) << std::setfill('0') << size - << "] "; - if (size >= 1000) { - ss << "... (too big to print)"; - continue; - } - for (size_t j = 0; j < size; j++) { - if (isText) - ss << static_cast(data[j]); - else - ss << std::hex << std::setw(2) << std::setfill('0') - << static_cast(data[j]); - } - } - return ss.str(); - } - - // Check if equal to other multipart - bool equal(const multipart_t *other) const ZMQ_NOTHROW - { - return *this == *other; - } - - bool operator==(const multipart_t &other) const ZMQ_NOTHROW - { - if (size() != other.size()) - return false; - for (size_t i = 0; i < size(); i++) - if (at(i) != other.at(i)) - return false; - return true; - } - - bool operator!=(const multipart_t &other) const ZMQ_NOTHROW - { - return !(*this == other); - } - -#ifdef ZMQ_CPP11 - - // Return single part message_t encoded from this multipart_t. - message_t encode() const { return zmq::encode(*this); } - - // Decode encoded message into multiple parts and append to self. - void decode_append(const message_t &encoded) - { - zmq::decode(encoded, std::back_inserter(*this)); - } - - // Return a new multipart_t containing the decoded message_t. - static multipart_t decode(const message_t &encoded) - { - multipart_t tmp; - zmq::decode(encoded, std::back_inserter(tmp)); - return tmp; - } - -#endif - - private: - // Disable implicit copying (moving is more efficient) - multipart_t(const multipart_t &other) ZMQ_DELETED_FUNCTION; - void operator=(const multipart_t &other) ZMQ_DELETED_FUNCTION; -}; // class multipart_t - -inline std::ostream &operator<<(std::ostream &os, const multipart_t &msg) -{ - return os << msg.str(); -} - -#endif // ZMQ_HAS_RVALUE_REFS - -#if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER) -class active_poller_t -{ - public: - active_poller_t() = default; - ~active_poller_t() = default; - - active_poller_t(const active_poller_t &) = delete; - active_poller_t &operator=(const active_poller_t &) = delete; - - active_poller_t(active_poller_t &&src) = default; - active_poller_t &operator=(active_poller_t &&src) = default; - - using handler_type = std::function; - - void add(zmq::socket_ref socket, event_flags events, handler_type handler) - { - const poller_ref_t ref{socket}; - - if (!handler) - throw std::invalid_argument("null handler in active_poller_t::add (socket)"); - auto ret = handlers.emplace( - ref, std::make_shared(std::move(handler))); - if (!ret.second) - throw error_t(EINVAL); // already added - try { - base_poller.add(socket, events, ret.first->second.get()); - need_rebuild = true; - } - catch (...) { - // rollback - handlers.erase(ref); - throw; - } - } - - void add(fd_t fd, event_flags events, handler_type handler) - { - const poller_ref_t ref{fd}; - - if (!handler) - throw std::invalid_argument("null handler in active_poller_t::add (fd)"); - auto ret = handlers.emplace( - ref, std::make_shared(std::move(handler))); - if (!ret.second) - throw error_t(EINVAL); // already added - try { - base_poller.add(fd, events, ret.first->second.get()); - need_rebuild = true; - } - catch (...) { - // rollback - handlers.erase(ref); - throw; - } - } - - void remove(zmq::socket_ref socket) - { - base_poller.remove(socket); - handlers.erase(socket); - need_rebuild = true; - } - - void remove(fd_t fd) - { - base_poller.remove(fd); - handlers.erase(fd); - need_rebuild = true; - } - - void modify(zmq::socket_ref socket, event_flags events) - { - base_poller.modify(socket, events); - } - - void modify(fd_t fd, event_flags events) - { - base_poller.modify(fd, events); - } - - size_t wait(std::chrono::milliseconds timeout) - { - if (need_rebuild) { - poller_events.resize(handlers.size()); - poller_handlers.clear(); - poller_handlers.reserve(handlers.size()); - for (const auto &handler : handlers) { - poller_handlers.push_back(handler.second); - } - need_rebuild = false; - } - const auto count = base_poller.wait_all(poller_events, timeout); - std::for_each(poller_events.begin(), - poller_events.begin() + static_cast(count), - [](decltype(base_poller)::event_type &event) { - assert(event.user_data != nullptr); - (*event.user_data)(event.events); - }); - return count; - } - - ZMQ_NODISCARD bool empty() const noexcept { return handlers.empty(); } - - size_t size() const noexcept { return handlers.size(); } - - private: - bool need_rebuild{false}; - - poller_t base_poller{}; - - std::unordered_map> handlers{}; - - std::vector poller_events{}; - std::vector> poller_handlers{}; -}; // class active_poller_t -#endif // defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER) - - -} // namespace zmq - -#endif // __ZMQ_ADDON_HPP_INCLUDED__ diff --git a/3rdparty/flatbuffers/base.h b/3rdparty/flatbuffers/base.h deleted file mode 100644 index 1c19dde98..000000000 --- a/3rdparty/flatbuffers/base.h +++ /dev/null @@ -1,496 +0,0 @@ -#ifndef FLATBUFFERS_BASE_H_ -#define FLATBUFFERS_BASE_H_ - -// clang-format off - -// If activate should be declared and included first. -#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \ - defined(_MSC_VER) && defined(_DEBUG) - // The _CRTDBG_MAP_ALLOC inside will replace - // calloc/free (etc) to its debug version using #define directives. - #define _CRTDBG_MAP_ALLOC - #include - #include - // Replace operator new by trace-enabled version. - #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) - #define new DEBUG_NEW -#endif - -#if !defined(FLATBUFFERS_ASSERT) -#include -#define FLATBUFFERS_ASSERT assert -#elif defined(FLATBUFFERS_ASSERT_INCLUDE) -// Include file with forward declaration -#include FLATBUFFERS_ASSERT_INCLUDE -#endif - -#ifndef ARDUINO -#include -#endif - -#include -#include -#include - -#if defined(ARDUINO) && !defined(ARDUINOSTL_M_H) && defined(__AVR__) - #include -#else - #include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__unix__) && !defined(FLATBUFFERS_LOCALE_INDEPENDENT) - #include -#endif - -#ifdef __ANDROID__ - #include -#endif - -#if defined(__ICCARM__) -#include -#endif - -// Note the __clang__ check is needed, because clang presents itself -// as an older GNUC compiler (4.2). -// Clang 3.3 and later implement all of the ISO C++ 2011 standard. -// Clang 3.4 and later implement all of the ISO C++ 2014 standard. -// http://clang.llvm.org/cxx_status.html - -// Note the MSVC value '__cplusplus' may be incorrect: -// The '__cplusplus' predefined macro in the MSVC stuck at the value 199711L, -// indicating (erroneously!) that the compiler conformed to the C++98 Standard. -// This value should be correct starting from MSVC2017-15.7-Preview-3. -// The '__cplusplus' will be valid only if MSVC2017-15.7-P3 and the `/Zc:__cplusplus` switch is set. -// Workaround (for details see MSDN): -// Use the _MSC_VER and _MSVC_LANG definition instead of the __cplusplus for compatibility. -// The _MSVC_LANG macro reports the Standard version regardless of the '/Zc:__cplusplus' switch. - -#if defined(__GNUC__) && !defined(__clang__) - #define FLATBUFFERS_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#else - #define FLATBUFFERS_GCC 0 -#endif - -#if defined(__clang__) - #define FLATBUFFERS_CLANG (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) -#else - #define FLATBUFFERS_CLANG 0 -#endif - -/// @cond FLATBUFFERS_INTERNAL -#if __cplusplus <= 199711L && \ - (!defined(_MSC_VER) || _MSC_VER < 1600) && \ - (!defined(__GNUC__) || \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40400)) - #error A C++11 compatible compiler with support for the auto typing is \ - required for FlatBuffers. - #error __cplusplus _MSC_VER __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ -#endif - -#if !defined(__clang__) && \ - defined(__GNUC__) && \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600) - // Backwards compatibility for g++ 4.4, and 4.5 which don't have the nullptr - // and constexpr keywords. Note the __clang__ check is needed, because clang - // presents itself as an older GNUC compiler. - #ifndef nullptr_t - const class nullptr_t { - public: - template inline operator T*() const { return 0; } - private: - void operator&() const; - } nullptr = {}; - #endif - #ifndef constexpr - #define constexpr const - #endif -#endif - -// The wire format uses a little endian encoding (since that's efficient for -// the common platforms). -#if defined(__s390x__) - #define FLATBUFFERS_LITTLEENDIAN 0 -#endif // __s390x__ -#if !defined(FLATBUFFERS_LITTLEENDIAN) - #if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__) - #if (defined(__BIG_ENDIAN__) || \ - (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) - #define FLATBUFFERS_LITTLEENDIAN 0 - #else - #define FLATBUFFERS_LITTLEENDIAN 1 - #endif // __BIG_ENDIAN__ - #elif defined(_MSC_VER) - #if defined(_M_PPC) - #define FLATBUFFERS_LITTLEENDIAN 0 - #else - #define FLATBUFFERS_LITTLEENDIAN 1 - #endif - #else - #error Unable to determine endianness, define FLATBUFFERS_LITTLEENDIAN. - #endif -#endif // !defined(FLATBUFFERS_LITTLEENDIAN) - -#define FLATBUFFERS_VERSION_MAJOR 24 -#define FLATBUFFERS_VERSION_MINOR 3 -#define FLATBUFFERS_VERSION_REVISION 25 -#define FLATBUFFERS_STRING_EXPAND(X) #X -#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X) -namespace flatbuffers { - // Returns version as string "MAJOR.MINOR.REVISION". - const char* FLATBUFFERS_VERSION(); -} - -#if (!defined(_MSC_VER) || _MSC_VER > 1600) && \ - (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)) || \ - defined(__clang__) - #define FLATBUFFERS_FINAL_CLASS final - #define FLATBUFFERS_OVERRIDE override - #define FLATBUFFERS_EXPLICIT_CPP11 explicit - #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE : ::flatbuffers::voffset_t -#else - #define FLATBUFFERS_FINAL_CLASS - #define FLATBUFFERS_OVERRIDE - #define FLATBUFFERS_EXPLICIT_CPP11 - #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE -#endif - -#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \ - (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \ - (defined(__cpp_constexpr) && __cpp_constexpr >= 200704) - #define FLATBUFFERS_CONSTEXPR constexpr - #define FLATBUFFERS_CONSTEXPR_CPP11 constexpr - #define FLATBUFFERS_CONSTEXPR_DEFINED -#else - #define FLATBUFFERS_CONSTEXPR const - #define FLATBUFFERS_CONSTEXPR_CPP11 -#endif - -#if (defined(__cplusplus) && __cplusplus >= 201402L) || \ - (defined(__cpp_constexpr) && __cpp_constexpr >= 201304) - #define FLATBUFFERS_CONSTEXPR_CPP14 FLATBUFFERS_CONSTEXPR_CPP11 -#else - #define FLATBUFFERS_CONSTEXPR_CPP14 -#endif - -#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \ - (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023026)) || \ - defined(__clang__) - #define FLATBUFFERS_NOEXCEPT noexcept -#else - #define FLATBUFFERS_NOEXCEPT -#endif - -// NOTE: the FLATBUFFERS_DELETE_FUNC macro may change the access mode to -// private, so be sure to put it at the end or reset access mode explicitly. -#if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \ - (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)) || \ - defined(__clang__) - #define FLATBUFFERS_DELETE_FUNC(func) func = delete -#else - #define FLATBUFFERS_DELETE_FUNC(func) private: func -#endif - -#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \ - (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \ - defined(__clang__) - #define FLATBUFFERS_DEFAULT_DECLARATION -#endif - -// Check if we can use template aliases -// Not possible if Microsoft Compiler before 2012 -// Possible is the language feature __cpp_alias_templates is defined well -// Or possible if the C++ std is C+11 or newer -#if (defined(_MSC_VER) && _MSC_VER > 1700 /* MSVC2012 */) \ - || (defined(__cpp_alias_templates) && __cpp_alias_templates >= 200704) \ - || (defined(__cplusplus) && __cplusplus >= 201103L) - #define FLATBUFFERS_TEMPLATES_ALIASES -#endif - -#ifndef FLATBUFFERS_HAS_STRING_VIEW - // Only provide flatbuffers::string_view if __has_include can be used - // to detect a header that provides an implementation - #if defined(__has_include) - // Check for std::string_view (in c++17) - #if __has_include() && (__cplusplus >= 201606 || (defined(_HAS_CXX17) && _HAS_CXX17)) - #include - namespace flatbuffers { - typedef std::string_view string_view; - } - #define FLATBUFFERS_HAS_STRING_VIEW 1 - // Check for std::experimental::string_view (in c++14, compiler-dependent) - #elif __has_include() && (__cplusplus >= 201411) - #include - namespace flatbuffers { - typedef std::experimental::string_view string_view; - } - #define FLATBUFFERS_HAS_STRING_VIEW 1 - // Check for absl::string_view - #elif __has_include("absl/strings/string_view.h") && \ - __has_include("absl/base/config.h") && \ - (__cplusplus >= 201411) - #include "absl/base/config.h" - #if !defined(ABSL_USES_STD_STRING_VIEW) - #include "absl/strings/string_view.h" - namespace flatbuffers { - typedef absl::string_view string_view; - } - #define FLATBUFFERS_HAS_STRING_VIEW 1 - #endif - #endif - #endif // __has_include -#endif // !FLATBUFFERS_HAS_STRING_VIEW - -#ifndef FLATBUFFERS_GENERAL_HEAP_ALLOC_OK - // Allow heap allocations to be used - #define FLATBUFFERS_GENERAL_HEAP_ALLOC_OK 1 -#endif // !FLATBUFFERS_GENERAL_HEAP_ALLOC_OK - -#ifndef FLATBUFFERS_HAS_NEW_STRTOD - // Modern (C++11) strtod and strtof functions are available for use. - // 1) nan/inf strings as argument of strtod; - // 2) hex-float as argument of strtod/strtof. - #if (defined(_MSC_VER) && _MSC_VER >= 1900) || \ - (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \ - (defined(__clang__)) - #define FLATBUFFERS_HAS_NEW_STRTOD 1 - #endif -#endif // !FLATBUFFERS_HAS_NEW_STRTOD - -#ifndef FLATBUFFERS_LOCALE_INDEPENDENT - // Enable locale independent functions {strtof_l, strtod_l,strtoll_l, - // strtoull_l}. - #if (defined(_MSC_VER) && _MSC_VER >= 1800) || \ - (defined(__ANDROID_API__) && __ANDROID_API__>= 21) || \ - (defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 700)) && \ - (!defined(__Fuchsia__) && !defined(__ANDROID_API__)) - #define FLATBUFFERS_LOCALE_INDEPENDENT 1 - #else - #define FLATBUFFERS_LOCALE_INDEPENDENT 0 - #endif -#endif // !FLATBUFFERS_LOCALE_INDEPENDENT - -// Suppress Undefined Behavior Sanitizer (recoverable only). Usage: -// - FLATBUFFERS_SUPPRESS_UBSAN("undefined") -// - FLATBUFFERS_SUPPRESS_UBSAN("signed-integer-overflow") -#if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7)) - #define FLATBUFFERS_SUPPRESS_UBSAN(type) __attribute__((no_sanitize(type))) -#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409) - #define FLATBUFFERS_SUPPRESS_UBSAN(type) __attribute__((no_sanitize_undefined)) -#else - #define FLATBUFFERS_SUPPRESS_UBSAN(type) -#endif - -namespace flatbuffers { - // This is constexpr function used for checking compile-time constants. - // Avoid `#pragma warning(disable: 4127) // C4127: expression is constant`. - template FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) { - return !!t; - } -} - -// Enable C++ attribute [[]] if std:c++17 or higher. -#if ((__cplusplus >= 201703L) \ - || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L))) - // All attributes unknown to an implementation are ignored without causing an error. - #define FLATBUFFERS_ATTRIBUTE(attr) attr - - #define FLATBUFFERS_FALLTHROUGH() [[fallthrough]] -#else - #define FLATBUFFERS_ATTRIBUTE(attr) - - #if FLATBUFFERS_CLANG >= 30800 - #define FLATBUFFERS_FALLTHROUGH() [[clang::fallthrough]] - #elif FLATBUFFERS_GCC >= 70300 - #define FLATBUFFERS_FALLTHROUGH() [[gnu::fallthrough]] - #else - #define FLATBUFFERS_FALLTHROUGH() - #endif -#endif - -/// @endcond - -/// @file -namespace flatbuffers { - -/// @cond FLATBUFFERS_INTERNAL -// Our default offset / size type, 32bit on purpose on 64bit systems. -// Also, using a consistent offset type maintains compatibility of serialized -// offset values between 32bit and 64bit systems. -typedef uint32_t uoffset_t; -typedef uint64_t uoffset64_t; - -// Signed offsets for references that can go in both directions. -typedef int32_t soffset_t; -typedef int64_t soffset64_t; - -// Offset/index used in v-tables, can be changed to uint8_t in -// format forks to save a bit of space if desired. -typedef uint16_t voffset_t; - -typedef uintmax_t largest_scalar_t; - -// In 32bits, this evaluates to 2GB - 1 -#define FLATBUFFERS_MAX_BUFFER_SIZE std::numeric_limits<::flatbuffers::soffset_t>::max() -#define FLATBUFFERS_MAX_64_BUFFER_SIZE std::numeric_limits<::flatbuffers::soffset64_t>::max() - -// The minimum size buffer that can be a valid flatbuffer. -// Includes the offset to the root table (uoffset_t), the offset to the vtable -// of the root table (soffset_t), the size of the vtable (uint16_t), and the -// size of the referring table (uint16_t). -#define FLATBUFFERS_MIN_BUFFER_SIZE sizeof(uoffset_t) + sizeof(soffset_t) + \ - sizeof(uint16_t) + sizeof(uint16_t) - -// We support aligning the contents of buffers up to this size. -#ifndef FLATBUFFERS_MAX_ALIGNMENT - #define FLATBUFFERS_MAX_ALIGNMENT 32 -#endif - -/// @brief The length of a FlatBuffer file header. -static const size_t kFileIdentifierLength = 4; - -inline bool VerifyAlignmentRequirements(size_t align, size_t min_align = 1) { - return (min_align <= align) && (align <= (FLATBUFFERS_MAX_ALIGNMENT)) && - (align & (align - 1)) == 0; // must be power of 2 -} - -#if defined(_MSC_VER) - #pragma warning(push) - #pragma warning(disable: 4127) // C4127: conditional expression is constant -#endif - -template T EndianSwap(T t) { - #if defined(_MSC_VER) - #define FLATBUFFERS_BYTESWAP16 _byteswap_ushort - #define FLATBUFFERS_BYTESWAP32 _byteswap_ulong - #define FLATBUFFERS_BYTESWAP64 _byteswap_uint64 - #elif defined(__ICCARM__) - #define FLATBUFFERS_BYTESWAP16 __REV16 - #define FLATBUFFERS_BYTESWAP32 __REV - #define FLATBUFFERS_BYTESWAP64(x) \ - ((__REV(static_cast(x >> 32U))) | (static_cast(__REV(static_cast(x)))) << 32U) - #else - #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__) - // __builtin_bswap16 was missing prior to GCC 4.8. - #define FLATBUFFERS_BYTESWAP16(x) \ - static_cast(__builtin_bswap32(static_cast(x) << 16)) - #else - #define FLATBUFFERS_BYTESWAP16 __builtin_bswap16 - #endif - #define FLATBUFFERS_BYTESWAP32 __builtin_bswap32 - #define FLATBUFFERS_BYTESWAP64 __builtin_bswap64 - #endif - if (sizeof(T) == 1) { // Compile-time if-then's. - return t; - } else if (sizeof(T) == 2) { - union { T t; uint16_t i; } u = { t }; - u.i = FLATBUFFERS_BYTESWAP16(u.i); - return u.t; - } else if (sizeof(T) == 4) { - union { T t; uint32_t i; } u = { t }; - u.i = FLATBUFFERS_BYTESWAP32(u.i); - return u.t; - } else if (sizeof(T) == 8) { - union { T t; uint64_t i; } u = { t }; - u.i = FLATBUFFERS_BYTESWAP64(u.i); - return u.t; - } else { - FLATBUFFERS_ASSERT(0); - return t; - } -} - -#if defined(_MSC_VER) - #pragma warning(pop) -#endif - - -template T EndianScalar(T t) { - #if FLATBUFFERS_LITTLEENDIAN - return t; - #else - return EndianSwap(t); - #endif -} - -template -// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. -FLATBUFFERS_SUPPRESS_UBSAN("alignment") -T ReadScalar(const void *p) { - return EndianScalar(*reinterpret_cast(p)); -} - -// See https://github.com/google/flatbuffers/issues/5950 - -#if (FLATBUFFERS_GCC >= 100000) && (FLATBUFFERS_GCC < 110000) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wstringop-overflow" -#endif - -template -// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. -FLATBUFFERS_SUPPRESS_UBSAN("alignment") -void WriteScalar(void *p, T t) { - *reinterpret_cast(p) = EndianScalar(t); -} - -template struct Offset; -template FLATBUFFERS_SUPPRESS_UBSAN("alignment") void WriteScalar(void *p, Offset t) { - *reinterpret_cast(p) = EndianScalar(t.o); -} - -#if (FLATBUFFERS_GCC >= 100000) && (FLATBUFFERS_GCC < 110000) - #pragma GCC diagnostic pop -#endif - -// Computes how many bytes you'd have to pad to be able to write an -// "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in -// memory). -FLATBUFFERS_SUPPRESS_UBSAN("unsigned-integer-overflow") -inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) { - return ((~buf_size) + 1) & (scalar_size - 1); -} - -// Generic 'operator==' with conditional specialisations. -// T e - new value of a scalar field. -// T def - default of scalar (is known at compile-time). -template inline bool IsTheSameAs(T e, T def) { return e == def; } - -#if defined(FLATBUFFERS_NAN_DEFAULTS) && \ - defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0) -// Like `operator==(e, def)` with weak NaN if T=(float|double). -template inline bool IsFloatTheSameAs(T e, T def) { - return (e == def) || ((def != def) && (e != e)); -} -template<> inline bool IsTheSameAs(float e, float def) { - return IsFloatTheSameAs(e, def); -} -template<> inline bool IsTheSameAs(double e, double def) { - return IsFloatTheSameAs(e, def); -} -#endif - -// Check 'v' is out of closed range [low; high]. -// Workaround for GCC warning [-Werror=type-limits]: -// comparison is always true due to limited range of data type. -template -inline bool IsOutRange(const T &v, const T &low, const T &high) { - return (v < low) || (high < v); -} - -// Check 'v' is in closed range [low; high]. -template -inline bool IsInRange(const T &v, const T &low, const T &high) { - return !IsOutRange(v, low, high); -} - -} // namespace flatbuffers -#endif // FLATBUFFERS_BASE_H_ diff --git a/3rdparty/lexy/CMakeLists.txt b/3rdparty/lexy/CMakeLists.txt deleted file mode 100644 index a76693a9e..000000000 --- a/3rdparty/lexy/CMakeLists.txt +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright (C) 2020-2024 Jonathan MÃŧller and lexy contributors -# SPDX-License-Identifier: BSL-1.0 - -cmake_minimum_required(VERSION 3.8) -project(lexy VERSION 2022.12.1 LANGUAGES CXX) - -set(LEXY_USER_CONFIG_HEADER "" CACHE FILEPATH "The user config header for lexy.") -option(LEXY_FORCE_CPP17 "Whether or not lexy should use C++17 even if compiler supports C++20." OFF) - -add_subdirectory(src) - -option(LEXY_ENABLE_INSTALL "whether or not to enable the install rule" ON) -if(LEXY_ENABLE_INSTALL) - include(CMakePackageConfigHelpers) - include(GNUInstallDirs) - - install(TARGETS lexy lexy_core lexy_file lexy_unicode lexy_ext _lexy_base lexy_dev - EXPORT ${PROJECT_NAME}Targets - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) - - install(EXPORT ${PROJECT_NAME}Targets - NAMESPACE foonathan:: - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") - - configure_package_config_file( - cmake/lexyConfig.cmake.in - "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" - INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") - install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") - - # YYYY.MM.N1 is compatible with YYYY.MM.N2. - write_basic_package_version_file( - "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" - COMPATIBILITY SameMinorVersion) - - install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") - - install(DIRECTORY include/lexy include/lexy_ext - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - FILES_MATCHING - PATTERN "*.hpp") -endif() - -if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) - cmake_minimum_required(VERSION 3.18) - option(LEXY_BUILD_BENCHMARKS "whether or not benchmarks should be built" OFF) - option(LEXY_BUILD_EXAMPLES "whether or not examples should be built" ON) - option(LEXY_BUILD_TESTS "whether or not tests should be built" ON) - option(LEXY_BUILD_DOCS "whether or not docs should be built" OFF) - option(LEXY_BUILD_PACKAGE "whether or not the package should be built" ON) - - if(LEXY_BUILD_PACKAGE) - set(package_files include/ src/ cmake/ CMakeLists.txt LICENSE) - add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lexy-src.zip - COMMAND ${CMAKE_COMMAND} -E tar c ${CMAKE_CURRENT_BINARY_DIR}/lexy-src.zip --format=zip -- ${package_files} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - DEPENDS ${package_files}) - add_custom_target(lexy_package DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/lexy-src.zip) - endif() - - if(LEXY_BUILD_EXAMPLES) - add_subdirectory(examples) - endif() - if(LEXY_BUILD_BENCHMARKS) - add_subdirectory(benchmarks) - endif() - if(LEXY_BUILD_TESTS) - set(DOCTEST_NO_INSTALL ON) - enable_testing() - add_subdirectory(tests) - endif() - if(LEXY_BUILD_DOCS) - add_subdirectory(docs EXCLUDE_FROM_ALL) - endif() -endif() diff --git a/3rdparty/lexy/LICENSE b/3rdparty/lexy/LICENSE deleted file mode 100644 index 36b7cd93c..000000000 --- a/3rdparty/lexy/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -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, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN 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/3rdparty/lexy/README.adoc b/3rdparty/lexy/README.adoc deleted file mode 100644 index 6bc88487f..000000000 --- a/3rdparty/lexy/README.adoc +++ /dev/null @@ -1,175 +0,0 @@ -= lexy - -ifdef::env-github[] -image:https://img.shields.io/endpoint?url=https%3A%2F%2Fwww.jonathanmueller.dev%2Fproject%2Flexy%2Findex.json[Project Status,link=https://www.jonathanmueller.dev/project/] -image:https://github.com/foonathan/lexy/workflows/Main%20CI/badge.svg[Build Status] -image:https://img.shields.io/badge/try_it_online-blue[Playground,link=https://lexy.foonathan.net/playground] -endif::[] - -lexy is a parser combinator library for {cpp}17 and onwards. -It allows you to write a parser by specifying it in a convenient {cpp} DSL, -which gives you all the flexibility and control of a handwritten parser without any of the manual work. - -ifdef::env-github[] -*Documentation*: https://lexy.foonathan.net/[lexy.foonathan.net] -endif::[] - -.IPv4 address parser --- -ifndef::env-github[] -[.godbolt-example] -.+++{{< svg "icons/play.svg" >}}+++ -endif::[] -[source,cpp] ----- -namespace dsl = lexy::dsl; - -// Parse an IPv4 address into a `std::uint32_t`. -struct ipv4_address -{ - // What is being matched. - static constexpr auto rule = []{ - // Match a sequence of (decimal) digits and convert it into a std::uint8_t. - auto octet = dsl::integer; - - // Match four of them separated by periods. - return dsl::times<4>(octet, dsl::sep(dsl::period)) + dsl::eof; - }(); - - // How the matched output is being stored. - static constexpr auto value - = lexy::callback([](std::uint8_t a, std::uint8_t b, std::uint8_t c, std::uint8_t d) { - return (a << 24) | (b << 16) | (c << 8) | d; - }); -}; ----- --- - -== Features - -Full control:: - * *Describe the parser, not some abstract grammar*: - Unlike parser generators that use some table driven magic for parsing, lexy's grammar is just syntax sugar for a hand-written recursive descent parser. - The parsing algorithm does exactly what you've instructed it to do -- no more ambiguities or weird shift/reduce errors! - * *No implicit backtracking or lookahead*: - It will only backtrack when you say it should, and only lookahead when and how far you want it. - Don't worry about rules that have side-effects, they won't be executed unnecessarily thanks to the user-specified lookahead conditions. - https://lexy.foonathan.net/playground?example=peek[Try it online]. - * *Escape hatch for manual parsing*: - Sometimes you want to parse something that can't be expressed easily with lexy's facilities. - Don't worry, you can integrate a hand-written parser into the grammar at any point. - https://lexy.foonathan.net/playground/?example=scan[Try it online]. - * *Tracing*: - Figure out why the grammar isn't working the way you want it to. - https://lexy.foonathan.net/playground/?example=trace&mode=trace[Try it online]. - -Easily integrated:: - * *A pure {cpp} DSL*: - No need to use an external grammar file; embed the grammar directly in your {cpp} project using operator overloading and functions. - * *Bring your own data structures*: - You can directly store results into your own types and have full control over all heap allocations. - * *Fully `constexpr` parsing*: - You want to parse a string literal at compile-time? You can do so. - * *Minimal standard library dependencies*: - The core parsing library only depends on fundamental headers such as `` or ``; no big includes like `` or ``. - * *Header-only core library* (by necessity, not by choice -- it's `constexpr` after all). - -ifdef::env-github[Designed for text::] -ifndef::env-github[Designed for text (e.g. {{< github-example json >}}, {{< github-example xml >}}, {{< github-example email >}}) ::] - * *Unicode support*: parse UTF-8, UTF-16, or UTF-32, and access the Unicode character database to query char classes or perform case folding. - https://lexy.foonathan.net/playground?example=identifier-unicode[Try it online]. - * *Convenience*: - Built-in rules for parsing nested structures, quotes and escape sequences. - https://lexy.foonathan.net/playground?example=parenthesized[Try it online]. - * *Automatic whitespace skipping*: - No need to manually handle whitespace or comments. - https://lexy.foonathan.net/playground/?example=whitespace_comment[Try it online]. - -ifdef::env-github[Designed for programming languages::] -ifndef::env-github[Designed for programming languages (e.g. {{< github-example calculator >}}, {{< github-example shell >}})::] - * *Keyword and identifier parsing*: - Reserve a set of keywords that won't be matched as regular identifiers. - https://lexy.foonathan.net/playground/?example=reserved_identifier[Try it online]. - * *Operator parsing*: - Parse unary/binary operators with different precedences and associativity, including chained comparisons `a < b < c`. - https://lexy.foonathan.net/playground/?example=expr[Try it online]. - * *Automatic error recovery*: - Log an error, recover, and continue parsing! - https://lexy.foonathan.net/playground/?example=recover[Try it online]. - -ifdef::env-github[Designed for binary input::] -ifndef::env-github[Designed for binary input (e.g. {{< github-example protobuf >}})::] - * *Bytes*: Rules for parsing `N` bytes or Nbit big/little endian integer. - * *Bits*: Rules for parsing individual bit patterns. - * *Blobs*: Rules for parsing TLV formats. - -== FAQ - -Why should I use lexy over XYZ?:: - lexy is closest to other PEG parsers. - However, they usually do more implicit backtracking, which can hurt performance and you need to be very careful with rules that have side-effects. - This is not the case for lexy, where backtracking is controlled using branch conditions. - lexy also gives you a lot of control over error reporting, supports error recovery, special support for operator precedence parsing, and other advanced features. - - http://boost-spirit.com/home/[Boost.Spirit]::: - The main difference: it is not a Boost library. - In addition, Boost.Spirit is quite old and doesn't support e.g. non-common ranges as input. - Boost.Spirit also eagerly creates attributes from the rules, which can lead to nested tuples/variants while lexy uses callbacks which enables zero-copy parsing directly into your own data structure. - However, lexy's grammar is more verbose and designed to parser bigger grammars instead of the small one-off rules that Boost.Spirit is good at. - https://github.com/taocpp/PEGTL[PEGTL]::: - PEGTL is very similar and was a big inspiration. - The biggest difference is that lexy uses an operator based DSL instead of inheriting from templated classes as PEGTL does; - depending on your preference this can be an advantage or disadvantage. - Hand-written Parsers::: - Writing a handwritten parser is more manual work and error prone. - lexy automates that away without having to sacrifice control. - You can use it to quickly prototype a parser and then slowly replace more and more with a handwritten parser over time; - mixing a hand-written parser and a lexy grammar works seamlessly. - -How bad are the compilation times?:: -They're not as bad as you might expect (in debug mode, that is). -+ -The example JSON parser compiles in about 2s on my machine. -If we remove all the lexy specific parts and just benchmark the time it takes for the compiler to process the datastructure (and stdlib includes), -that takes about 700ms. -If we validate JSON only instead of parsing it, so remove the data structures and keep only the lexy specific parts, we're looking at about 840ms. -+ -Keep in mind, that you can fully isolate lexy in a single translation unit that only needs to be touched when you change the parser. -You can also split a lexy grammar into multiple translation units using the `dsl::subgrammar` rule. - -How bad are the {cpp} error messages if you mess something up?:: - They're certainly worse than the error message lexy gives you. - The big problem here is that the first line gives you the error, followed by dozens of template instantiations, which end at your `lexy::parse` call. - Besides providing an external tool to filter those error messages, there is nothing I can do about that. - -How fast is it?:: - Benchmarks are available in the `benchmarks/` directory. - A sample result of the JSON validator benchmark which compares the example JSON parser with various other implementations is available https://lexy.foonathan.net/benchmark_json/[here]. - -Why is it called lexy?:: - I previously had a tokenizer library called foonathan/lex. - I've tried adding a parser to it, but found that the line between pure tokenization and parsing has become increasingly blurred. - lexy is a re-imagination on of the parser I've added to foonathan/lex, and I've simply kept a similar name. - -ifdef::env-github[] -== Documentation - -The documentation, including tutorials, reference documentation, and an interactive playground can be found at https://lexy.foonathan.net/[lexy.foonathan.net]. - -A minimal `CMakeLists.txt` that uses lexy can look like this: - -.`CMakeLists.txt` -```cmake -project(lexy-example) - -include(FetchContent) -FetchContent_Declare(lexy URL https://lexy.foonathan.net/download/lexy-src.zip) -FetchContent_MakeAvailable(lexy) - -add_executable(lexy_example) -target_sources(lexy_example PRIVATE main.cpp) -target_link_libraries(lexy_example PRIVATE foonathan::lexy) -``` - -endif::[] - diff --git a/3rdparty/lexy/cmake/lexyConfig.cmake.in b/3rdparty/lexy/cmake/lexyConfig.cmake.in deleted file mode 100644 index e6dc89d30..000000000 --- a/3rdparty/lexy/cmake/lexyConfig.cmake.in +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) 2020-2024 Jonathan MÃŧller and lexy contributors -# SPDX-License-Identifier: BSL-1.0 - -# lexy CMake configuration file. - -@PACKAGE_INIT@ - -include ("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") diff --git a/3rdparty/lexy/include/lexy/_detail/any_ref.hpp b/3rdparty/lexy/include/lexy/_detail/any_ref.hpp deleted file mode 100644 index 9eca714b2..000000000 --- a/3rdparty/lexy/include/lexy/_detail/any_ref.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2020-2024 Jonathan MÃŧller and lexy contributors -// SPDX-License-Identifier: BSL-1.0 - -#ifndef LEXY_DETAIL_ANY_REF_HPP_INCLUDED -#define LEXY_DETAIL_ANY_REF_HPP_INCLUDED - -#include - -// Essentially a void*, but we can cast it in a constexpr context. -// The cost is an extra layer of indirection. - -namespace lexy::_detail -{ -template -class any_holder; - -// Store a pointer to this instead of a void*. -class any_base -{ -public: - any_base(const any_base&) = delete; - any_base& operator=(const any_base&) = delete; - - template - constexpr T& get() noexcept - { - return static_cast*>(this)->get(); - } - template - constexpr const T& get() const noexcept - { - return static_cast*>(this)->get(); - } - -private: - constexpr any_base() = default; - ~any_base() = default; - - template - friend class any_holder; -}; - -using any_ref = any_base*; -using any_cref = const any_base*; - -// Need to store the object in here. -template -class any_holder : public any_base -{ -public: - constexpr explicit any_holder(T&& obj) : _obj(LEXY_MOV(obj)) {} - - constexpr T& get() noexcept - { - return _obj; - } - constexpr const T& get() const noexcept - { - return _obj; - } - -private: - T _obj; -}; -} // namespace lexy::_detail - -#endif // LEXY_DETAIL_ANY_REF_HPP_INCLUDED - diff --git a/3rdparty/lexy/include/lexy/_detail/assert.hpp b/3rdparty/lexy/include/lexy/_detail/assert.hpp deleted file mode 100644 index 52aa115de..000000000 --- a/3rdparty/lexy/include/lexy/_detail/assert.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2020-2024 Jonathan MÃŧller and lexy contributors -// SPDX-License-Identifier: BSL-1.0 - -#ifndef LEXY_DETAIL_ASSERT_HPP_INCLUDED -#define LEXY_DETAIL_ASSERT_HPP_INCLUDED - -#include - -#ifndef LEXY_ENABLE_ASSERT - -// By default, enable assertions if NDEBUG is not defined. - -# if NDEBUG -# define LEXY_ENABLE_ASSERT 0 -# else -# define LEXY_ENABLE_ASSERT 1 -# endif - -#endif - -#if LEXY_ENABLE_ASSERT - -// We want assertions: use assert() if that's available, otherwise abort. -// We don't use assert() directly as that's not constexpr. - -# if NDEBUG - -# include -# define LEXY_PRECONDITION(Expr) ((Expr) ? void(0) : std::abort()) -# define LEXY_ASSERT(Expr, Msg) ((Expr) ? void(0) : std::abort()) - -# else - -# include - -# define LEXY_PRECONDITION(Expr) ((Expr) ? void(0) : assert(Expr)) -# define LEXY_ASSERT(Expr, Msg) ((Expr) ? void(0) : assert((Expr) && (Msg))) - -# endif - -#else - -// We don't want assertions. - -# define LEXY_PRECONDITION(Expr) static_cast(sizeof(Expr)) -# define LEXY_ASSERT(Expr, Msg) static_cast(sizeof(Expr)) - -#endif - -#endif // LEXY_DETAIL_ASSERT_HPP_INCLUDED - diff --git a/3rdparty/lexy/include/lexy/_detail/buffer_builder.hpp b/3rdparty/lexy/include/lexy/_detail/buffer_builder.hpp deleted file mode 100644 index 94ba1fd27..000000000 --- a/3rdparty/lexy/include/lexy/_detail/buffer_builder.hpp +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (C) 2020-2024 Jonathan MÃŧller and lexy contributors -// SPDX-License-Identifier: BSL-1.0 - -#ifndef LEXY_DETAIL_BUFFER_BUILDER_HPP_INCLUDED -#define LEXY_DETAIL_BUFFER_BUILDER_HPP_INCLUDED - -#include -#include -#include -#include -#include - -namespace lexy::_detail -{ -// Builds a buffer: it has a read are and a write area. -// The characters in the read area are already valid and can be read. -// The characters in the write area are not valid, but can be written too. -template -class buffer_builder -{ - static_assert(std::is_trivial_v); - - static constexpr std::size_t total_size_bytes = 1024; - static constexpr std::size_t stack_buffer_size - = (total_size_bytes - 3 * sizeof(T*)) / sizeof(T); - static constexpr auto growth_factor = 2; - -public: - buffer_builder() noexcept : _data(_stack_buffer), _read_size(0), _write_size(stack_buffer_size) - { - static_assert(sizeof(*this) == total_size_bytes, "invalid buffer size calculation"); - } - - ~buffer_builder() noexcept - { - // Free memory if we allocated any. - if (_data != _stack_buffer) - ::operator delete(_data); - } - - buffer_builder(const buffer_builder&) = delete; - buffer_builder& operator=(const buffer_builder&) = delete; - - // The total capacity: read + write. - std::size_t capacity() const noexcept - { - return _read_size + _write_size; - } - - // The read area. - const T* read_data() const noexcept - { - return _data; - } - std::size_t read_size() const noexcept - { - return _read_size; - } - - // The write area. - T* write_data() noexcept - { - return _data + _read_size; - } - std::size_t write_size() const noexcept - { - return _write_size; - } - - // Clears the read area. - void clear() noexcept - { - _write_size += _read_size; - _read_size = 0; - } - - // Takes the first n characters of the write area and appends them to the read area. - void commit(std::size_t n) noexcept - { - LEXY_PRECONDITION(n <= _write_size); - _read_size += n; - _write_size -= n; - } - - // Increases the write area, invalidates all pointers. - void grow() - { - const auto cur_cap = capacity(); - const auto new_cap = growth_factor * cur_cap; - - // Allocate new memory. - auto memory = static_cast(::operator new(new_cap * sizeof(T))); - // Copy the read area into the new memory. - std::memcpy(memory, _data, _read_size); - - // Release the old memory, if there was any. - if (_data != _stack_buffer) - ::operator delete(_data); - - // Update for the new area. - _data = memory; - // _read_size hasn't been changed - _write_size = new_cap - _read_size; - } - - //=== iterator ===// - // Stable iterator over the memory. - class stable_iterator : public forward_iterator_base - { - public: - constexpr stable_iterator() = default; - - explicit constexpr stable_iterator(const _detail::buffer_builder& buffer, - std::size_t idx) noexcept - : _buffer(&buffer), _idx(idx) - {} - - constexpr const T& deref() const noexcept - { - LEXY_PRECONDITION(_idx != _buffer->read_size()); - return _buffer->read_data()[_idx]; - } - - constexpr void increment() noexcept - { - LEXY_PRECONDITION(_idx != _buffer->read_size()); - ++_idx; - } - - constexpr bool equal(stable_iterator rhs) const noexcept - { - if (!_buffer || !rhs._buffer) - return !_buffer && !rhs._buffer; - else - { - LEXY_PRECONDITION(_buffer == rhs._buffer); - return _idx == rhs._idx; - } - } - - constexpr std::size_t index() const noexcept - { - return _idx; - } - - private: - const _detail::buffer_builder* _buffer = nullptr; - std::size_t _idx = 0; - }; - -private: - T* _data; - std::size_t _read_size; - std::size_t _write_size; - T _stack_buffer[stack_buffer_size]; -}; -} // namespace lexy::_detail - -#endif // LEXY_DETAIL_BUFFER_BUILDER_HPP_INCLUDED - diff --git a/3rdparty/lexy/include/lexy/_detail/code_point.hpp b/3rdparty/lexy/include/lexy/_detail/code_point.hpp deleted file mode 100644 index bc805b11e..000000000 --- a/3rdparty/lexy/include/lexy/_detail/code_point.hpp +++ /dev/null @@ -1,368 +0,0 @@ -// Copyright (C) 2020-2024 Jonathan MÃŧller and lexy contributors -// SPDX-License-Identifier: BSL-1.0 - -#ifndef LEXY_DETAIL_CODE_POINT_HPP_INCLUDED -#define LEXY_DETAIL_CODE_POINT_HPP_INCLUDED - -#include - -//=== encoding ===// -namespace lexy::_detail -{ -template -constexpr std::size_t encode_code_point(char32_t cp, typename Encoding::char_type* buffer, - std::size_t size) -{ - if constexpr (std::is_same_v) - { - LEXY_PRECONDITION(size >= 1); - - *buffer = char(cp); - return 1; - } - else if constexpr (std::is_same_v // - || std::is_same_v) - { - using char_type = typename Encoding::char_type; - // Taken from http://www.herongyang.com/Unicode/UTF-8-UTF-8-Encoding-Algorithm.html. - if (cp <= 0x7F) - { - LEXY_PRECONDITION(size >= 1); - - buffer[0] = char_type(cp); - return 1; - } - else if (cp <= 0x07'FF) - { - LEXY_PRECONDITION(size >= 2); - - auto first = (cp >> 6) & 0x1F; - auto second = (cp >> 0) & 0x3F; - - buffer[0] = char_type(0xC0 | first); - buffer[1] = char_type(0x80 | second); - return 2; - } - else if (cp <= 0xFF'FF) - { - LEXY_PRECONDITION(size >= 3); - - auto first = (cp >> 12) & 0x0F; - auto second = (cp >> 6) & 0x3F; - auto third = (cp >> 0) & 0x3F; - - buffer[0] = char_type(0xE0 | first); - buffer[1] = char_type(0x80 | second); - buffer[2] = char_type(0x80 | third); - return 3; - } - else - { - LEXY_PRECONDITION(size >= 4); - - auto first = (cp >> 18) & 0x07; - auto second = (cp >> 12) & 0x3F; - auto third = (cp >> 6) & 0x3F; - auto fourth = (cp >> 0) & 0x3F; - - buffer[0] = char_type(0xF0 | first); - buffer[1] = char_type(0x80 | second); - buffer[2] = char_type(0x80 | third); - buffer[3] = char_type(0x80 | fourth); - return 4; - } - } - else if constexpr (std::is_same_v) - { - if (cp <= 0xFF'FF) - { - LEXY_PRECONDITION(size >= 1); - - buffer[0] = char16_t(cp); - return 1; - } - else - { - // Algorithm implemented from - // https://en.wikipedia.org/wiki/UTF-16#Code_points_from_U+010000_to_U+10FFFF. - LEXY_PRECONDITION(size >= 2); - - auto u_prime = cp - 0x1'0000; - auto high_ten_bits = u_prime >> 10; - auto low_ten_bits = u_prime & 0b0000'0011'1111'1111; - - buffer[0] = char16_t(0xD800 + high_ten_bits); - buffer[1] = char16_t(0xDC00 + low_ten_bits); - return 2; - } - } - else if constexpr (std::is_same_v) - { - LEXY_PRECONDITION(size >= 1); - - *buffer = char32_t(cp); - return 1; - } - else - { - static_assert(lexy::_detail::error, - "cannot encode a code point in this encoding"); - (void)cp; - (void)buffer; - (void)size; - return 0; - } -} -} // namespace lexy::_detail - -//=== parsing ===// -namespace lexy::_detail -{ -enum class cp_error -{ - success, - eof, - leads_with_trailing, - missing_trailing, - surrogate, - overlong_sequence, - out_of_range, -}; - -template -struct cp_result -{ - char32_t cp; - cp_error error; - typename Reader::marker end; -}; - -template -constexpr cp_result parse_code_point(Reader reader) -{ - if constexpr (std::is_same_v) - { - if (reader.peek() == Reader::encoding::eof()) - return {{}, cp_error::eof, reader.current()}; - - auto cur = reader.peek(); - reader.bump(); - - auto cp = static_cast(cur); - if (cp <= 0x7F) - return {cp, cp_error::success, reader.current()}; - else - return {cp, cp_error::out_of_range, reader.current()}; - } - else if constexpr (std::is_same_v // - || std::is_same_v) - { - using uchar_t = unsigned char; - constexpr auto payload_lead1 = 0b0111'1111; - constexpr auto payload_lead2 = 0b0001'1111; - constexpr auto payload_lead3 = 0b0000'1111; - constexpr auto payload_lead4 = 0b0000'0111; - constexpr auto payload_cont = 0b0011'1111; - - constexpr auto pattern_lead1 = 0b0 << 7; - constexpr auto pattern_lead2 = 0b110 << 5; - constexpr auto pattern_lead3 = 0b1110 << 4; - constexpr auto pattern_lead4 = 0b11110 << 3; - constexpr auto pattern_cont = 0b10 << 6; - - auto first = uchar_t(reader.peek()); - if ((first & ~payload_lead1) == pattern_lead1) - { - // ASCII character. - reader.bump(); - return {first, cp_error::success, reader.current()}; - } - else if ((first & ~payload_cont) == pattern_cont) - { - return {{}, cp_error::leads_with_trailing, reader.current()}; - } - else if ((first & ~payload_lead2) == pattern_lead2) - { - reader.bump(); - - auto second = uchar_t(reader.peek()); - if ((second & ~payload_cont) != pattern_cont) - return {{}, cp_error::missing_trailing, reader.current()}; - reader.bump(); - - auto result = char32_t(first & payload_lead2); - result <<= 6; - result |= char32_t(second & payload_cont); - - // C0 and C1 are overlong ASCII. - if (first == 0xC0 || first == 0xC1) - return {result, cp_error::overlong_sequence, reader.current()}; - else - return {result, cp_error::success, reader.current()}; - } - else if ((first & ~payload_lead3) == pattern_lead3) - { - reader.bump(); - - auto second = uchar_t(reader.peek()); - if ((second & ~payload_cont) != pattern_cont) - return {{}, cp_error::missing_trailing, reader.current()}; - reader.bump(); - - auto third = uchar_t(reader.peek()); - if ((third & ~payload_cont) != pattern_cont) - return {{}, cp_error::missing_trailing, reader.current()}; - reader.bump(); - - auto result = char32_t(first & payload_lead3); - result <<= 6; - result |= char32_t(second & payload_cont); - result <<= 6; - result |= char32_t(third & payload_cont); - - auto cp = result; - if (0xD800 <= cp && cp <= 0xDFFF) - return {cp, cp_error::surrogate, reader.current()}; - else if (first == 0xE0 && second < 0xA0) - return {cp, cp_error::overlong_sequence, reader.current()}; - else - return {cp, cp_error::success, reader.current()}; - } - else if ((first & ~payload_lead4) == pattern_lead4) - { - reader.bump(); - - auto second = uchar_t(reader.peek()); - if ((second & ~payload_cont) != pattern_cont) - return {{}, cp_error::missing_trailing, reader.current()}; - reader.bump(); - - auto third = uchar_t(reader.peek()); - if ((third & ~payload_cont) != pattern_cont) - return {{}, cp_error::missing_trailing, reader.current()}; - reader.bump(); - - auto fourth = uchar_t(reader.peek()); - if ((fourth & ~payload_cont) != pattern_cont) - return {{}, cp_error::missing_trailing, reader.current()}; - reader.bump(); - - auto result = char32_t(first & payload_lead4); - result <<= 6; - result |= char32_t(second & payload_cont); - result <<= 6; - result |= char32_t(third & payload_cont); - result <<= 6; - result |= char32_t(fourth & payload_cont); - - auto cp = result; - if (cp > 0x10'FFFF) - return {cp, cp_error::out_of_range, reader.current()}; - else if (first == 0xF0 && second < 0x90) - return {cp, cp_error::overlong_sequence, reader.current()}; - else - return {cp, cp_error::success, reader.current()}; - } - else // FE or FF - { - return {{}, cp_error::eof, reader.current()}; - } - } - else if constexpr (std::is_same_v) - { - constexpr auto payload1 = 0b0000'0011'1111'1111; - constexpr auto payload2 = payload1; - - constexpr auto pattern1 = 0b110110 << 10; - constexpr auto pattern2 = 0b110111 << 10; - - if (reader.peek() == Reader::encoding::eof()) - return {{}, cp_error::eof, reader.current()}; - - auto first = char16_t(reader.peek()); - if ((first & ~payload1) == pattern1) - { - reader.bump(); - if (reader.peek() == Reader::encoding::eof()) - return {{}, cp_error::missing_trailing, reader.current()}; - - auto second = char16_t(reader.peek()); - if ((second & ~payload2) != pattern2) - return {{}, cp_error::missing_trailing, reader.current()}; - reader.bump(); - - // We've got a valid code point. - auto result = char32_t(first & payload1); - result <<= 10; - result |= char32_t(second & payload2); - result |= 0x10000; - return {result, cp_error::success, reader.current()}; - } - else if ((first & ~payload2) == pattern2) - { - return {{}, cp_error::leads_with_trailing, reader.current()}; - } - else - { - // Single code unit code point; always valid. - reader.bump(); - return {first, cp_error::success, reader.current()}; - } - } - else if constexpr (std::is_same_v) - { - if (reader.peek() == Reader::encoding::eof()) - return {{}, cp_error::eof, reader.current()}; - - auto cur = reader.peek(); - reader.bump(); - - auto cp = cur; - if (cp > 0x10'FFFF) - return {cp, cp_error::out_of_range, reader.current()}; - else if (0xD800 <= cp && cp <= 0xDFFF) - return {cp, cp_error::surrogate, reader.current()}; - else - return {cp, cp_error::success, reader.current()}; - } - else - { - static_assert(lexy::_detail::error, - "no known code point for this encoding"); - return {}; - } -} - -template -constexpr void recover_code_point(Reader& reader, cp_result result) -{ - switch (result.error) - { - case cp_error::success: - // Consume the entire code point. - reader.reset(result.end); - break; - case cp_error::eof: - // We don't need to do anything to "recover" from EOF. - break; - - case cp_error::leads_with_trailing: - // Invalid code unit, consume to recover. - LEXY_PRECONDITION(result.end.position() == reader.position()); - reader.bump(); - break; - - case cp_error::missing_trailing: - case cp_error::surrogate: - case cp_error::out_of_range: - case cp_error::overlong_sequence: - // Consume all the invalid code units to recover. - reader.reset(result.end); - break; - } -} -} // namespace lexy::_detail - -#endif // LEXY_DETAIL_CODE_POINT_HPP_INCLUDED - diff --git a/3rdparty/lexy/include/lexy/_detail/config.hpp b/3rdparty/lexy/include/lexy/_detail/config.hpp deleted file mode 100644 index 4aa40135b..000000000 --- a/3rdparty/lexy/include/lexy/_detail/config.hpp +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright (C) 2020-2024 Jonathan MÃŧller and lexy contributors -// SPDX-License-Identifier: BSL-1.0 - -#ifndef LEXY_DETAIL_CONFIG_HPP_INCLUDED -#define LEXY_DETAIL_CONFIG_HPP_INCLUDED - -#include -#include - -#if defined(LEXY_USER_CONFIG_HEADER) -# include LEXY_USER_CONFIG_HEADER -#elif defined(__has_include) -# if __has_include() -# include -# elif __has_include("lexy_user_config.hpp") -# include "lexy_user_config.hpp" -# endif -#endif - -#ifndef LEXY_HAS_UNICODE_DATABASE -# define LEXY_HAS_UNICODE_DATABASE 0 -#endif - -#ifndef LEXY_EXPERIMENTAL -# define LEXY_EXPERIMENTAL 0 -#endif - -//=== utility traits===// -#define LEXY_MOV(...) static_cast&&>(__VA_ARGS__) -#define LEXY_FWD(...) static_cast(__VA_ARGS__) - -#define LEXY_DECLVAL(...) lexy::_detail::declval<__VA_ARGS__>() - -#define LEXY_DECAY_DECLTYPE(...) std::decay_t - -/// Creates a new type from the instantiation of a template. -/// This is used to shorten type names. -#define LEXY_INSTANTIATION_NEWTYPE(Name, Templ, ...) \ - struct Name : Templ<__VA_ARGS__> \ - { \ - using Templ<__VA_ARGS__>::Templ; \ - } - -namespace lexy::_detail -{ -template -constexpr bool error = false; - -template -std::add_rvalue_reference_t declval(); - -template -constexpr void swap(T& lhs, T& rhs) -{ - T tmp = LEXY_MOV(lhs); - lhs = LEXY_MOV(rhs); - rhs = LEXY_MOV(tmp); -} - -template -constexpr bool is_decayed_same = std::is_same_v, std::decay_t>; - -template -using type_or = std::conditional_t, Fallback, T>; -} // namespace lexy::_detail - -//=== NTTP ===// -#ifndef LEXY_HAS_NTTP -// See https://github.com/foonathan/lexy/issues/15. -# if __cpp_nontype_template_parameter_class >= 201806 || __cpp_nontype_template_args >= 201911 -# define LEXY_HAS_NTTP 1 -# else -# define LEXY_HAS_NTTP 0 -# endif -#endif - -#if LEXY_HAS_NTTP -# define LEXY_NTTP_PARAM auto -#else -# define LEXY_NTTP_PARAM const auto& -#endif - -//=== consteval ===// -#ifndef LEXY_HAS_CONSTEVAL -# if defined(_MSC_VER) && !defined(__clang__) -// Currently can't handle returning strings from consteval, check back later. -# define LEXY_HAS_CONSTEVAL 0 -# elif __cpp_consteval -# define LEXY_HAS_CONSTEVAL 1 -# else -# define LEXY_HAS_CONSTEVAL 0 -# endif -#endif - -#if LEXY_HAS_CONSTEVAL -# define LEXY_CONSTEVAL consteval -#else -# define LEXY_CONSTEVAL constexpr -#endif - -//=== constexpr ===// -#ifndef LEXY_HAS_CONSTEXPR_DTOR -# if __cpp_constexpr_dynamic_alloc -# define LEXY_HAS_CONSTEXPR_DTOR 1 -# else -# define LEXY_HAS_CONSTEXPR_DTOR 0 -# endif -#endif - -#if LEXY_HAS_CONSTEXPR_DTOR -# define LEXY_CONSTEXPR_DTOR constexpr -#else -# define LEXY_CONSTEXPR_DTOR -#endif - -//=== char8_t ===// -#ifndef LEXY_HAS_CHAR8_T -# if __cpp_char8_t -# define LEXY_HAS_CHAR8_T 1 -# else -# define LEXY_HAS_CHAR8_T 0 -# endif -#endif - -#if LEXY_HAS_CHAR8_T - -# define LEXY_CHAR_OF_u8 char8_t -# define LEXY_CHAR8_T char8_t -# define LEXY_CHAR8_STR(Str) u8##Str - -#else - -namespace lexy -{ -using _char8_t = unsigned char; -} // namespace lexy - -# define LEXY_CHAR_OF_u8 char -# define LEXY_CHAR8_T ::lexy::_char8_t -# define LEXY_CHAR8_STR(Str) \ - LEXY_NTTP_STRING(::lexy::_detail::type_string, u8##Str)::c_str - -#endif - -//=== endianness ===// -#ifndef LEXY_IS_LITTLE_ENDIAN -# if defined(__BYTE_ORDER__) -# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define LEXY_IS_LITTLE_ENDIAN 1 -# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# define LEXY_IS_LITTLE_ENDIAN 0 -# else -# error "unsupported byte order" -# endif -# elif defined(_MSC_VER) -# define LEXY_IS_LITTLE_ENDIAN 1 -# else -# error "unknown endianness" -# endif -#endif - -//=== force inline ===// -#ifndef LEXY_FORCE_INLINE -# if defined(__has_cpp_attribute) -# if __has_cpp_attribute(gnu::always_inline) -# define LEXY_FORCE_INLINE [[gnu::always_inline]] -# endif -# endif -# -# ifndef LEXY_FORCE_INLINE -# define LEXY_FORCE_INLINE inline -# endif -#endif - -//=== empty_member ===// -#ifndef LEXY_EMPTY_MEMBER - -# if defined(__has_cpp_attribute) -# if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 11 -// GCC <= 11 has buggy support, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101040 -# define LEXY_HAS_EMPTY_MEMBER 0 -# elif __has_cpp_attribute(no_unique_address) -# define LEXY_HAS_EMPTY_MEMBER 1 -# endif -# endif -# ifndef LEXY_HAS_EMPTY_MEMBER -# define LEXY_HAS_EMPTY_MEMBER 0 -# endif - -# if LEXY_HAS_EMPTY_MEMBER -# define LEXY_EMPTY_MEMBER [[no_unique_address]] -# else -# define LEXY_EMPTY_MEMBER -# endif - -#endif - -#endif // LEXY_DETAIL_CONFIG_HPP_INCLUDED - diff --git a/3rdparty/lexy/include/lexy/_detail/detect.hpp b/3rdparty/lexy/include/lexy/_detail/detect.hpp deleted file mode 100644 index 7534c44c4..000000000 --- a/3rdparty/lexy/include/lexy/_detail/detect.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2020-2024 Jonathan MÃŧller and lexy contributors -// SPDX-License-Identifier: BSL-1.0 - -#ifndef LEXY_DETAIL_DETECT_HPP_INCLUDED -#define LEXY_DETAIL_DETECT_HPP_INCLUDED - -#include - -namespace lexy::_detail -{ -template -using void_t = void; - -template