diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index f01c556e8..000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve openpilot -title: '' -labels: 'bug' -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**How to reproduce or log data** -Steps to reproduce the behavior, or a explorer/cabana link to the exact drive and timestamp of when the bug occurred. - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Device/Version information (please complete the following information):** - - Device: [e.g. EON/EON Gold] - - Version: [e.g. 0.6.4], or commit hash when on devel - - Car make/model [e.g. Toyota Prius 2016] - -**Additional context** -Add any other context about the problem here. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index 72e1845d7..000000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,21 +0,0 @@ -Choose one of the templates below: - -# Fingerprint -This pull requests adds a fingerprint for . - -This is an explorer link to a drive with the stock system enabled: ... - -# Car support -This pull requests adds support for . - -This is an explorer link to a drive with the stock system enabled: ... -This is an explorer link to a drive with openpilot system enabled: ... - -# Feature -This pull requests adds feature X - -## Description -Explain what the feature does - -## Testing -Explain how the feature was tested. Either by the added unit tests, or what tests were performed while driving. diff --git a/.gitignore b/.gitignore index 9f2de0181..b8d9a39b4 100644 --- a/.gitignore +++ b/.gitignore @@ -54,11 +54,15 @@ openpilot notebooks xx panda_jungle +apks +openpilot-apks .coverage* coverage.xml -cppcheck_report.txt htmlcov pandaextra .mypy_cache/ +flycheck_* + +cppcheck_report.txt diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e101650d4..b8564c1e8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,7 +22,7 @@ All PRs and commits are automatically checked by Github Actions. Check out `.git ### Code Style and Linting -Code is automatically checked for style by Github Actions as part of the automated tests. You can also run these tests yourself by running `pylint_openpilot.sh` and `flake8_openpilot.sh`. +Code is automatically checked for style by Github Actions as part of the automated tests. You can also run these tests yourself by running `pre-commit run --all`. ## Car Ports (openpilot) diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000..c36251203 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,89 @@ +pipeline { + agent { + docker { + image 'python:3.7.3' + args '--user=root' + } + } + environment { + COMMA_JWT = credentials('athena-test-jwt') + } + + stages { + + stage('Release Build') { + when { + branch 'devel-staging' + } + steps { + lock(resource: "", label: 'eon-build', inversePrecedence: true, variable: 'eon_ip', quantity: 1){ + timeout(time: 60, unit: 'MINUTES') { + dir(path: 'selfdrive/test') { + sh 'pip install paramiko' + sh 'python phone_ci.py "cd release && PUSH=1 ./build_release2.sh"' + } + } + } + } + } + + stage('On-device Tests') { + when { + not { + anyOf { + branch 'master-ci'; branch 'devel'; branch 'devel-staging'; branch 'release2'; branch 'release2-staging'; branch 'dashcam'; branch 'dashcam-staging' + } + } + } + + parallel { + + stage('Build') { + environment { + CI_PUSH = "${env.BRANCH_NAME == 'master' ? 'master-ci' : ''}" + } + + steps { + lock(resource: "", label: 'eon', inversePrecedence: true, variable: 'eon_ip', quantity: 1){ + timeout(time: 60, unit: 'MINUTES') { + dir(path: 'selfdrive/test') { + sh 'pip install paramiko' + sh 'python phone_ci.py "cd release && ./build_devel.sh"' + } + } + } + } + } + + stage('Replay Tests') { + steps { + lock(resource: "", label: 'eon2', inversePrecedence: true, variable: 'eon_ip', quantity: 1){ + timeout(time: 60, unit: 'MINUTES') { + dir(path: 'selfdrive/test') { + sh 'pip install paramiko' + sh 'python phone_ci.py "cd selfdrive/test/process_replay && ./camera_replay.py"' + } + } + } + } + } + + stage('HW Tests') { + steps { + lock(resource: "", label: 'eon', inversePrecedence: true, variable: 'eon_ip', quantity: 1){ + timeout(time: 60, unit: 'MINUTES') { + dir(path: 'selfdrive/test') { + sh 'pip install paramiko' + sh 'python phone_ci.py "SCONS_CACHE=1 scons -j3 cereal/ && \ + nosetests -s selfdrive/test/test_sounds.py && \ + nosetests -s selfdrive/boardd/tests/test_boardd_loopback.py"' + } + } + } + } + } + + } + } + } +} diff --git a/README.md b/README.md index 80c48babe..052828cf1 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ Supported Cars | Acura | ILX 2016-18 | AcuraWatch Plus | openpilot | 25mph1 | 25mph | | Acura | RDX 2016-18 | AcuraWatch Plus | openpilot | 25mph1 | 12mph | | Honda | Accord 2018-19 | All | Stock | 0mph | 3mph | -| Honda | Accord Hybrid 2018-19 | All | Stock | 0mph | 3mph | +| Honda | Accord Hybrid 2018-20 | All | Stock | 0mph | 3mph | | Honda | Civic Hatchback 2017-19 | Honda Sensing | Stock | 0mph | 12mph | | Honda | Civic Sedan/Coupe 2016-18 | Honda Sensing | openpilot | 0mph | 12mph | | Honda | Civic Sedan/Coupe 2019-20 | Honda Sensing | Stock | 0mph | 2mph2 | @@ -82,6 +82,7 @@ Supported Cars | Honda | Pilot 2016-18 | Honda Sensing | openpilot | 25mph1 | 12mph | | Honda | Pilot 2019 | All | openpilot | 25mph1 | 12mph | | Honda | Ridgeline 2017-20 | Honda Sensing | openpilot | 25mph1 | 12mph | +| Hyundai | Sonata 2020 | All | Stock | 0mph | 0mph | | Lexus | CT Hybrid 2017-18 | All | Stock3| 0mph | 0mph | | Lexus | ES 2019 | All | openpilot | 0mph | 0mph | | Lexus | ES Hybrid 2019 | All | openpilot | 0mph | 0mph | @@ -107,7 +108,7 @@ Supported Cars | Toyota | Highlander 2020 | All | openpilot | 0mph | 0mph | | Toyota | Highlander Hybrid 2020 | All | openpilot | 0mph | 0mph | | Toyota | Prius 2016 | TSS-P | Stock3| 0mph | 0mph | -| Toyota | Prius 2017-19 | All | Stock3| 0mph | 0mph | +| Toyota | Prius 2017-20 | All | Stock3| 0mph | 0mph | | Toyota | Prius Prime 2017-20 | All | Stock3| 0mph | 0mph | | Toyota | Rav4 2016 | TSS-P | Stock3| 20mph1 | 0mph | | Toyota | Rav4 2017-18 | All | Stock3| 20mph1 | 0mph | @@ -117,9 +118,9 @@ Supported Cars | Toyota | Rav4 Hybrid 2019-20 | All | openpilot | 0mph | 0mph | | Toyota | Sienna 2018-20 | All | Stock3| 0mph | 0mph | -1[Comma Pedal](https://community.comma.ai/wiki/index.php/Comma_Pedal) is used to provide stop-and-go capability to some of the openpilot-supported cars that don't currently support stop-and-go. Here is how to [build a Comma Pedal](https://medium.com/@jfrux/comma-pedal-building-with-macrofab-6328bea791e8). ***NOTE: The Comma Pedal is not officially supported by [comma](https://comma.ai).***
+1[Comma Pedal](https://github.com/commaai/openpilot/wiki/comma-pedal) is used to provide stop-and-go capability to some of the openpilot-supported cars that don't currently support stop-and-go. ***NOTE: The Comma Pedal is not officially supported by [comma](https://comma.ai).***
22019 Honda Civic 1.6L Diesel Sedan does not have ALC below 12mph.
-3When disconnecting the Driver Support Unit (DSU), openpilot ACC will replace stock ACC. For DSU locations, see [Toyota Wiki page](https://community.comma.ai/wiki/index.php/Toyota). ***NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).***
+3When disconnecting the Driver Support Unit (DSU), openpilot ACC will replace stock ACC. ***NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).***
428mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control.
Community Maintained Cars and Features @@ -135,33 +136,37 @@ Community Maintained Cars and Features | Chrysler | Pacifica 2020 | Adaptive Cruise | Stock | 0mph | 39mph | | Chrysler | Pacifica Hybrid 2017-18 | Adaptive Cruise | Stock | 0mph | 9mph | | Chrysler | Pacifica Hybrid 2019-20 | Adaptive Cruise | Stock | 0mph | 39mph | -| Genesis | G80 20182 | All | Stock | 0mph | 0mph | +| Genesis | G80 2018 | All | Stock | 0mph | 0mph | | Genesis | G90 2018 | All | Stock | 0mph | 0mph | | GMC | Acadia Denali 20182| Adaptive Cruise | openpilot | 0mph | 7mph | | Holden | Astra 20171 | Adaptive Cruise | openpilot | 0mph | 7mph | -| Hyundai | Elantra 2017-192 | SCC + LKAS | Stock | 19mph | 34mph | -| Hyundai | Genesis 2015-162 | SCC + LKAS | Stock | 19mph | 37mph | -| Hyundai | Kona 2017-192 | SCC + LKAS | Stock | 22mph | 0mph | -| Hyundai | Kona 2019 EV2 | SCC + LKAS | Stock | 0mph | 0mph | -| Hyundai | Palisade 20202 | All | Stock | 0mph | 0mph | +| Hyundai | Elantra 2017-19 | SCC + LKAS | Stock | 19mph | 34mph | +| Hyundai | Genesis 2015-16 | SCC + LKAS | Stock | 19mph | 37mph | +| Hyundai | Ioniq Electric Premium SE 2020| SCC + LKAS | Stock | 0mph | 32mph | +| Hyundai | Ioniq Electric Limited 2019 | SCC + LKAS | Stock | 0mph | 32mph | +| Hyundai | Kona 2017-19 | SCC + LKAS | Stock | 22mph | 0mph | +| Hyundai | Kona EV 2019 | SCC + LKAS | Stock | 0mph | 0mph | +| Hyundai | Palisade 2020 | All | Stock | 0mph | 0mph | | Hyundai | Santa Fe 2019 | All | Stock | 0mph | 0mph | -| Hyundai | Sonata 2019-20 | All | Stock | 0mph | 0mph | +| Hyundai | Sonata 2019 | All | Stock | 0mph | 0mph | | Jeep | Grand Cherokee 2016-18 | Adaptive Cruise | Stock | 0mph | 9mph | -| Jeep | Grand Cherokee 2019 | Adaptive Cruise | Stock | 0mph | 39mph | -| Kia | Forte 2018-192 | SCC + LKAS | Stock | 0mph | 0mph | -| Kia | Optima 20172 | SCC + LKAS/LDWS | Stock | 0mph | 32mph | -| Kia | Optima 20192 | SCC + LKAS | Stock | 0mph | 0mph | -| Kia | Sorento 20182 | SCC + LKAS | Stock | 0mph | 0mph | -| Kia | Stinger 20182 | SCC + LKAS | Stock | 0mph | 0mph | +| Jeep | Grand Cherokee 2019-20 | Adaptive Cruise | Stock | 0mph | 39mph | +| Kia | Forte 2018-19 | SCC + LKAS | Stock | 0mph | 0mph | +| Kia | Optima 2017 | SCC + LKAS/LDWS | Stock | 0mph | 32mph | +| Kia | Optima 2019 | SCC + LKAS | Stock | 0mph | 0mph | +| Kia | Sorento 2018 | SCC + LKAS | Stock | 0mph | 0mph | +| Kia | Stinger 2018 | SCC + LKAS | Stock | 0mph | 0mph | | Nissan | Leaf 2018-192 | Propilot | Stock | 0mph | 0mph | | Nissan | Rogue 20192 | Propilot | Stock | 0mph | 0mph | | Nissan | X-Trail 20172 | Propilot | Stock | 0mph | 0mph | +| Subaru | Ascent 2019 | EyeSight | Stock | 0mph | 0mph | | Subaru | Crosstrek 2018-19 | EyeSight | Stock | 0mph | 0mph | -| Subaru | Impreza 2018-20 | EyeSight | Stock | 0mph | 0mph | +| Subaru | Forester 2019 | EyeSight | Stock | 0mph | 0mph | +| Subaru | Impreza 2017-19 | EyeSight | Stock | 0mph | 0mph | | Volkswagen| Golf 2015-19 | Driver Assistance | Stock | 0mph | 0mph | -1Requires a [panda](https://comma.ai/shop/products/panda-obd-ii-dongle) and [community built giraffe](https://zoneos.com/volt/). ***NOTE: disconnecting the ASCM disables Automatic Emergency Braking (AEB).***
-2May require a custom connector for the developer [car harness](https://comma.ai/shop/products/car-harness)
+1Requires an [OBD-II car harness](https://comma.ai/shop/products/comma-car-harness) and [community built giraffe](https://github.com/commaai/openpilot/wiki/GM). ***NOTE: disconnecting the ASCM disables Automatic Emergency Braking (AEB).***
+2Requires a custom connector for the developer [car harness](https://comma.ai/shop/products/car-harness)
Although it's not upstream, there's a community of people getting openpilot to run on Tesla's [here](https://tinkla.us/) @@ -174,7 +179,7 @@ Installation Instructions Install openpilot on an EON or comma two by entering ``https://openpilot.comma.ai`` during the installer setup. -Follow these [video instructions](https://youtu.be/3nlkomHathI) to properly mount the device on the windshield. Note: openpilot features an automatic pose calibration routine and openpilot performance should not be affected by small pitch and yaw misalignments caused by imprecise device mounting. +Follow these [video instructions](https://youtu.be/lcjqxCymins) to properly mount the device on the windshield. Note: openpilot features an automatic pose calibration routine and openpilot performance should not be affected by small pitch and yaw misalignments caused by imprecise device mounting. Before placing the device on your windshield, check the state and local laws and ordinances where you drive. Some state laws prohibit or restrict the placement of objects on the windshield of a motor vehicle. @@ -277,7 +282,7 @@ openpilot is developed by [comma](https://comma.ai/) and by users like you. We w You can add support for your car by following guides we have written for [Brand](https://medium.com/@comma_ai/how-to-write-a-car-port-for-openpilot-7ce0785eda84) and [Model](https://medium.com/@comma_ai/openpilot-port-guide-for-toyota-models-e5467f4b5fe6) ports. Generally, a car with adaptive cruise control and lane keep assist is a good candidate. [Join our Discord](https://discord.comma.ai) to discuss car ports: most car makes have a dedicated channel. -Want to get paid to work on openpilot? [comma is hiring](https://comma.ai/jobs/). We also have a [bounty program](https://comma.ai/bounties.html). +Want to get paid to work on openpilot? [comma is hiring](https://comma.ai/jobs/). And [follow us on Twitter](https://twitter.com/comma_ai). @@ -327,7 +332,7 @@ NO WARRANTY EXPRESSED OR IMPLIED.** -[![openpilot tests](https://github.com/commaai/openpilot/workflows/openpilot%20tests/badge.svg)](https://github.com/commaai/openpilot/actions) +[![openpilot tests](https://github.com/commaai/openpilot/workflows/openpilot%20tests/badge.svg?event=push)](https://github.com/commaai/openpilot/actions) [![Total alerts](https://img.shields.io/lgtm/alerts/g/commaai/openpilot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/commaai/openpilot/alerts/) [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/commaai/openpilot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/commaai/openpilot/context:python) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/commaai/openpilot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/commaai/openpilot/context:cpp) diff --git a/RELEASES.md b/RELEASES.md index e4eef1ff8..5559cd3c6 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,17 @@ +Version 0.7.7 (2020-07-20) +======================== + * White panda is no longer supported, upgrade to comma two or black panda + * Improved vehicle model estimation using high precision localizer + * Improved thermal management on comma two + * Improved autofocus for road-facing camera + * Improved noise performance for driver-facing camera + * Block lane change start using blindspot monitor on select Toyota, Hyundai, and Subaru + * Fix GM ignition detection + * Code cleanup and smaller release sizes + * Hyundai Sonata 2020 promoted to officially supported car + * Hyundai Ioniq Electric Limited 2019 and Ioniq SE 2020 support thanks to baldwalker! + * Subaru Forester 2019 and Ascent 2019 support thanks to martinl! + Version 0.7.6.1 (2020-06-16) ======================== * Hotfix: update kernel on some comma twos (orders #8570-#8680) diff --git a/SAFETY.md b/SAFETY.md index 5a3c287fe..9cf8933b9 100644 --- a/SAFETY.md +++ b/SAFETY.md @@ -1,7 +1,7 @@ openpilot Safety ====== -openpilot is an Adaptive Cruise Control (ACC) and Automated Lane Centering (ALC) system. +openpilot is an Adaptive Cruise Control (ACC) and Automated Lane Centering (ALC) system. Like other ACC and ALC systems, openpilot is a failsafe passive system and it requires the driver to be alert and to pay attention at all times. @@ -22,7 +22,7 @@ hardware-in-the-loop and in-vehicle tests before each software release. Following Hazard and Risk Analysis and FMEA, at a very high level, we have designed openpilot ensuring two main safety requirements. -1. The driver must always be capable to immediately retake manual control of the vehicle, +1. The driver must always be capable to immediately retake manual control of the vehicle, by stepping on either pedal or by pressing the cancel button. 2. The vehicle must not alter its trajectory too quickly for the driver to safely react. This means that while the system is engaged, the actuators are constrained diff --git a/SConstruct b/SConstruct index 285a1743b..7e5a412b5 100644 --- a/SConstruct +++ b/SConstruct @@ -1,4 +1,5 @@ import os +import shutil import subprocess import sys import platform @@ -18,6 +19,7 @@ if arch == "aarch64" and not os.path.isdir("/system"): arch = "larch64" webcam = bool(ARGUMENTS.get("use_webcam", 0)) +QCOM_REPLAY = arch == "aarch64" and os.getenv("QCOM_REPLAY") is not None if arch == "aarch64" or arch == "larch64": lenv = { @@ -43,20 +45,31 @@ if arch == "aarch64" or arch == "larch64": ] if arch == "larch64": - libpath += ["#phonelibs/snpe/larch64"] - libpath += ["#phonelibs/libyuv/larch64/lib"] - libpath += ["/usr/lib/aarch64-linux-gnu"] + libpath += [ + "#phonelibs/snpe/larch64", + "#phonelibs/libyuv/larch64/lib", + "/usr/lib/aarch64-linux-gnu" + ] cflags = ["-DQCOM2", "-mcpu=cortex-a57"] cxxflags = ["-DQCOM2", "-mcpu=cortex-a57"] rpath = ["/usr/local/lib"] else: - libpath += ["#phonelibs/snpe/aarch64"] - libpath += ["#phonelibs/libyuv/lib"] + libpath += [ + "#phonelibs/snpe/aarch64", + "#phonelibs/libyuv/lib" + ] cflags = ["-DQCOM", "-mcpu=cortex-a57"] cxxflags = ["-DQCOM", "-mcpu=cortex-a57"] rpath = ["/system/vendor/lib64"] + if QCOM_REPLAY: + cflags += ["-DQCOM_REPLAY"] + cxxflags += ["-DQCOM_REPLAY"] + else: + cflags = [] + cxxflags = [] + lenv = { "PATH": "#external/bin:" + os.environ['PATH'], } @@ -72,6 +85,8 @@ else: "/usr/local/lib", "/System/Library/Frameworks/OpenGL.framework/Libraries", ] + cflags += ["-DGL_SILENCE_DEPRECATION"] + cxxflags += ["-DGL_SILENCE_DEPRECATION"] else: libpath = [ "#phonelibs/snpe/x86_64-linux-clang", @@ -84,18 +99,20 @@ else: ] rpath = [ - "external/tensorflow/lib", - "cereal", - "selfdrive/common"] + "external/tensorflow/lib", + "cereal", + "selfdrive/common" + ] # allows shared libraries to work globally rpath = [os.path.join(os.getcwd(), x) for x in rpath] - cflags = [] - cxxflags = [] - -ccflags_asan = ["-fsanitize=address", "-fno-omit-frame-pointer"] if GetOption('asan') else [] -ldflags_asan = ["-fsanitize=address"] if GetOption('asan') else [] +if GetOption('asan'): + ccflags_asan = ["-fsanitize=address", "-fno-omit-frame-pointer"] + ldflags_asan = ["-fsanitize=address"] +else: + ccflags_asan = [] + ldflags_asan = [] # change pythonpath to this lenv["PYTHONPATH"] = Dir("#").path @@ -106,6 +123,7 @@ env = Environment( "-g", "-fPIC", "-O2", + "-Wunused", "-Werror", "-Wno-deprecated-register", "-Wno-inconsistent-missing-override", @@ -145,8 +163,7 @@ env = Environment( CFLAGS=["-std=gnu11"] + cflags, CXXFLAGS=["-std=c++14"] + cxxflags, - LIBPATH=libpath + - [ + LIBPATH=libpath + [ "#cereal", "#selfdrive/common", "#phonelibs", @@ -154,7 +171,19 @@ env = Environment( ) if os.environ.get('SCONS_CACHE'): - CacheDir('/tmp/scons_cache') + cache_dir = '/tmp/scons_cache' + + if os.getenv('CI'): + branch = os.getenv('GIT_BRANCH') + + if QCOM_REPLAY: + cache_dir = '/tmp/scons_cache_qcom_replay' + elif branch is not None and branch != 'master': + cache_dir_branch = '/tmp/scons_cache_' + branch + if not os.path.isdir(cache_dir_branch) and os.path.isdir(cache_dir): + shutil.copytree(cache_dir, cache_dir_branch) + cache_dir = cache_dir_branch + CacheDir(cache_dir) node_interval = 5 node_count = 0 @@ -179,7 +208,7 @@ def abspath(x): # still needed for apks zmq = 'zmq' -Export('env', 'arch', 'zmq', 'SHARED', 'webcam') +Export('env', 'arch', 'zmq', 'SHARED', 'webcam', 'QCOM_REPLAY') # cereal and messaging are shared with the system SConscript(['cereal/SConscript']) @@ -207,11 +236,11 @@ SConscript(['opendbc/can/SConscript']) SConscript(['common/SConscript']) SConscript(['common/kalman/SConscript']) +SConscript(['common/transformations/SConscript']) SConscript(['phonelibs/SConscript']) -if arch != "Darwin": - SConscript(['selfdrive/camerad/SConscript']) - SConscript(['selfdrive/modeld/SConscript']) +SConscript(['selfdrive/camerad/SConscript']) +SConscript(['selfdrive/modeld/SConscript']) SConscript(['selfdrive/controls/lib/cluster/SConscript']) SConscript(['selfdrive/controls/lib/lateral_mpc/SConscript']) diff --git a/apk/ai.comma.plus.offroad.apk b/apk/ai.comma.plus.offroad.apk index 0aabc2e38..f411e6365 100644 Binary files a/apk/ai.comma.plus.offroad.apk and b/apk/ai.comma.plus.offroad.apk differ diff --git a/cereal/.dockerignore b/cereal/.dockerignore deleted file mode 100644 index 5b2d46270..000000000 --- a/cereal/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -.sconsign.dblite diff --git a/cereal/.github/workflows/tests.yml b/cereal/.github/workflows/tests.yml deleted file mode 100644 index 51b836479..000000000 --- a/cereal/.github/workflows/tests.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Tests - -on: [push, pull_request] - -jobs: - test: - - runs-on: ubuntu-16.04 - - steps: - - uses: actions/checkout@v2 - - name: Build docker image - run: docker build -t cereal . - - name: Static analysis - run: | - docker run cereal bash -c "git init && git add -A && pre-commit run --all" - - name: Unit Tests - run: | - docker run cereal bash -c "scons --test --asan -j$(nproc) && messaging/test_runner" - - name: Test ZMQ - run: | - docker run cereal bash -c "ZMQ=1 python -m unittest discover ." - - name: Test MSGQ - run: | - docker run cereal bash -c "MSGQ=1 python -m unittest discover ." diff --git a/cereal/.pre-commit-config.yaml b/cereal/.pre-commit-config.yaml deleted file mode 100644 index 602d9d8ee..000000000 --- a/cereal/.pre-commit-config.yaml +++ /dev/null @@ -1,27 +0,0 @@ -repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: master - hooks: - - id: check-ast - - id: check-json - - id: check-xml - - id: check-yaml -- repo: https://github.com/pre-commit/mirrors-mypy - rev: master - hooks: - - id: mypy -- repo: https://github.com/PyCQA/flake8 - rev: master - hooks: - - id: flake8 - args: - - --select=F -- repo: local - hooks: - - id: pylint - name: pylint - entry: pylint - language: system - types: [python] - args: - - --disable=R,C,W diff --git a/cereal/Dockerfile b/cereal/Dockerfile deleted file mode 100644 index f4b8f2d69..000000000 --- a/cereal/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM ubuntu:16.04 - -RUN apt-get update && apt-get install -y libzmq3-dev capnproto libcapnp-dev clang wget git autoconf libtool curl make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python-openssl - -RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash -ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}" -RUN pyenv install 3.7.3 -RUN pyenv global 3.7.3 -RUN pyenv rehash -RUN pip3 install pyyaml==5.1.2 Cython==0.29.14 scons==3.1.1 pycapnp==0.6.4 pre-commit==2.4.0 pylint==2.5.2 - -WORKDIR /project/cereal - -ENV PYTHONPATH=/project - -COPY . . -RUN rm -rf .git -RUN scons -c && scons -j$(nproc) diff --git a/cereal/README.md b/cereal/README.md deleted file mode 100644 index d03e29439..000000000 --- a/cereal/README.md +++ /dev/null @@ -1,41 +0,0 @@ -What is cereal? ----- - -cereal is both a messaging spec for robotics systems as well as generic high performance IPC pub sub messaging with a single publisher and multiple subscribers. - -Imagine this use case: -* A sensor process reads gyro measurements directly from an IMU and publishes a sensorEvents packet -* A calibration process subscribes to the sensorEvents packet to use the IMU -* A localization process subscribes to the sensorEvents packet to use the IMU also - - -Messaging Spec ----- - -You'll find the message types in [log.capnp](log.capnp). It uses [Cap'n proto](https://capnproto.org/capnp-tool.html) and defines one struct called Event. - -All Events have a logMonoTime and a valid. Then a big union defines the packet type. - - -Pub Sub Backends ----- - -cereal supports two backends, one based on [zmq](https://zeromq.org/), the other called msgq, a custom pub sub based on shared memory that doesn't require the bytes to pass through the kernel. - -Example ---- -```python -import cereal.messaging as messaging - -# in subscriber -sm = messaging.SubMaster(['sensorEvents']) -while 1: - sm.update() - print(sm['sensorEvents']) - -# in publisher -pm = messaging.PubMaster(['sensorEvents']) -dat = messaging.new_message('sensorEvents', size=1) -dat.sensorEvents[0] = {"gyro": {"v": [0.1, -0.1, 0.1]}} -pm.send('sensorEvents', dat) -``` diff --git a/cereal/SConscript b/cereal/SConscript index a724dfa6b..ec651dd83 100644 --- a/cereal/SConscript +++ b/cereal/SConscript @@ -20,7 +20,6 @@ if shutil.which('capnpc-java'): cereal_objects = env.SharedObject([ 'gen/cpp/car.capnp.c++', 'gen/cpp/log.capnp.c++', - 'messaging/socketmaster.cc', ]) env.Library('cereal', cereal_objects) @@ -37,6 +36,7 @@ messaging_objects = env.SharedObject([ 'messaging/impl_zmq.cc', 'messaging/impl_msgq.cc', 'messaging/msgq.cc', + 'messaging/socketmaster.cc', ]) messaging_lib = env.Library('messaging', messaging_objects) @@ -46,7 +46,7 @@ Depends('messaging/impl_zmq.cc', services_h) # TODO: get APK to load system zmq to remove the static link if arch == "aarch64": zmq_static = FindFile("libzmq.a", "/usr/lib") - shared_lib_shared_lib = [zmq_static, 'm', 'stdc++', "gnustl_shared"] + shared_lib_shared_lib = [zmq_static, 'm', 'stdc++', "gnustl_shared", "kj", "capnp"] env.SharedLibrary('messaging_shared', messaging_objects, LIBS=shared_lib_shared_lib) env.Program('messaging/bridge', ['messaging/bridge.cc'], LIBS=[messaging_lib, 'zmq']) diff --git a/cereal/SConstruct b/cereal/SConstruct deleted file mode 100644 index a72286b27..000000000 --- a/cereal/SConstruct +++ /dev/null @@ -1,49 +0,0 @@ -import os -import subprocess - -zmq = 'zmq' -arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() - -cereal_dir = Dir('.') - -cpppath = [ - cereal_dir, - '/usr/lib/include', -] - -AddOption('--test', - action='store_true', - help='build test files') - -AddOption('--asan', - action='store_true', - help='turn on ASAN') - -ccflags_asan = ["-fsanitize=address", "-fno-omit-frame-pointer"] if GetOption('asan') else [] -ldflags_asan = ["-fsanitize=address"] if GetOption('asan') else [] - -env = Environment( - ENV=os.environ, - CC='clang', - CXX='clang++', - CCFLAGS=[ - "-g", - "-fPIC", - "-O2", - "-Werror=implicit-function-declaration", - "-Werror=incompatible-pointer-types", - "-Werror=int-conversion", - "-Werror=return-type", - "-Werror=format-extra-args", - ] + ccflags_asan, - LDFLAGS=ldflags_asan, - LINKFLAGS=ldflags_asan, - - CFLAGS="-std=gnu11", - CXXFLAGS="-std=c++14", - CPPPATH=cpppath, -) - - -Export('env', 'zmq', 'arch') -SConscript(['SConscript']) diff --git a/cereal/car.capnp b/cereal/car.capnp index 05c2dd6d2..5278006e6 100644 --- a/cereal/car.capnp +++ b/cereal/car.capnp @@ -93,7 +93,7 @@ struct CarEvent @0x9b1657f34caf3ad3 { driverMonitorLowAcc @68; invalidLkasSetting @69; speedTooHigh @70; - laneChangeBlockedDEPRECATED @71; + laneChangeBlocked @71; relayMalfunction @72; gasPressed @73; stockFcw @74; @@ -105,8 +105,13 @@ struct CarEvent @0x9b1657f34caf3ad3 { steerSaturated @80; whitePandaUnsupported @81; startupWhitePanda @82; - canErrorPersistent @83; + canErrorPersistentDEPRECATED @83; belowEngageSpeed @84; + noGps @85; + focusRecoverActive @86; + wrongCruiseMode @87; + neosUpdateRequired @88; + modeldLagging @89; } } @@ -188,6 +193,7 @@ struct CarState { available @2 :Bool; speedOffset @3 :Float32; standstill @4 :Bool; + nonAdaptive @5 :Bool; } enum GearShifter { @@ -467,6 +473,7 @@ struct CarParams { hondaBoschHarness @20; volkswagenPq @21; subaruLegacy @22; # pre-Global platform + hyundaiLegacy @23; } enum SteerControlType { diff --git a/cereal/generate_javascript.sh b/cereal/generate_javascript.sh deleted file mode 100755 index d6525a64d..000000000 --- a/cereal/generate_javascript.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -rm -r gen/ts -rm -r gen/js - -mkdir gen/ts -mkdir gen/js - -echo "Installing needed npm modules" -npm i capnpc-ts capnp-ts - -capnpc -o node_modules/.bin/capnpc-ts:gen/ts log.capnp car.capnp -capnpc -o node_modules/.bin/capnpc-ts:gen/ts car.capnp - -cat log.capnp | egrep '\([a-zA-Z]*\.[^\s]+\.[^s]+\)' | sed 's/^.*([a-zA-Z]*\.\([a-zA-Z.]*\)).*/\1/' | while read line -do - TOKEN=`echo $line | sed 's/\./_/g'` - ROOT=`echo $line | sed 's/\..*$//g'` - cat gen/ts/log.capnp.ts | grep '^import.*'${TOKEN} - if [[ "$?" == "1" ]] - then - sed -i 's/^\(import {.*\)'${ROOT}'\(,*\) \(.*\)$/\1'${ROOT}', '${TOKEN}'\2 \3/' ./gen/ts/log.capnp.ts - fi -done - -tsc ./gen/ts/* --lib es2015 --outDir ./gen/js diff --git a/cereal/install_capnp.sh b/cereal/install_capnp.sh deleted file mode 100755 index 2d2d43d61..000000000 --- a/cereal/install_capnp.sh +++ /dev/null @@ -1,12 +0,0 @@ -set -e -echo "Installing capnp" - -cd /tmp -VERSION=0.6.1 -wget https://capnproto.org/capnproto-c++-${VERSION}.tar.gz -tar xvf capnproto-c++-${VERSION}.tar.gz -cd capnproto-c++-${VERSION} -CXXFLAGS="-fPIC" ./configure - -make -j$(nproc) -make install diff --git a/cereal/log.capnp b/cereal/log.capnp index 4c64ee3b7..9d3021aff 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -130,6 +130,7 @@ struct FrameData { focusVal @16 :List(Int16); focusConf @17 :List(UInt8); sharpnessScore @18 :List(UInt16); + recoverState @19 :Int32; frameType @7 :FrameType; timestampSof @8 :UInt64; @@ -371,6 +372,7 @@ struct HealthData { interruptRateTim1 @16; interruptRateTim3 @17; registerDivergent @18; + interruptRateKlineInit @19; # Update max fault type in boardd when adding faults } @@ -381,6 +383,7 @@ struct HealthData { blackPanda @3; pedal @4; uno @5; + dos @6; } enum UsbPowerMode { @@ -596,8 +599,6 @@ struct ControlsState @0x97ff69c53601abf1 { lqrOutput @4 :Float32; saturated @5 :Bool; } - - } struct LiveEventData { @@ -607,6 +608,8 @@ struct LiveEventData { struct ModelData { frameId @0 :UInt32; + frameAge @12 :UInt32; + frameDropPerc @13 :Float32; timestampEof @9 :UInt64; path @1 :PathData; @@ -627,6 +630,7 @@ struct ModelData { std @2 :Float32; stds @3 :List(Float32); poly @4 :List(Float32); + validLen @5 :Float32; } struct LeadData { @@ -839,6 +843,7 @@ struct LiveLocationKalman { # These angles are all eulers and roll, pitch, yaw # orientationECEF transforms to rot matrix: ecef_from_device orientationECEF @6 : Measurement; + calibratedOrientationECEF @20 : Measurement; orientationNED @7 : Measurement; angularVelocityDevice @8 : Measurement; @@ -858,6 +863,7 @@ struct LiveLocationKalman { inputsOK @17 :Bool = true; posenetOK @18 :Bool = true; gpsOK @19 :Bool = true; + sensorsOK @21 :Bool = true; enum Status { uninitialized @0; @@ -1885,6 +1891,7 @@ struct DriverState { irPwrDEPRECATED @10 :Float32; faceOrientationStd @11 :List(Float32); facePositionStd @12 :List(Float32); + sgProb @13 :Float32; } struct DMonitoringState { diff --git a/cereal/maptile.capnp b/cereal/maptile.capnp deleted file mode 100644 index 336901392..000000000 --- a/cereal/maptile.capnp +++ /dev/null @@ -1,53 +0,0 @@ -using Cxx = import "./include/c++.capnp"; -$Cxx.namespace("cereal"); - -using Java = import "./include/java.capnp"; -$Java.package("ai.comma.openpilot.cereal"); -$Java.outerClassname("Map"); - -@0xa086df597ef5d7a0; - -# Geometry -struct Point { - x @0: Float64; - y @1: Float64; - z @2: Float64; -} - -struct PolyLine { - points @0: List(Point); -} - -# Map features -struct Lane { - id @0 :Text; - - leftBoundary @1 :LaneBoundary; - rightBoundary @2 :LaneBoundary; - - leftAdjacentId @3 :Text; - rightAdjacentId @4 :Text; - - inboundIds @5 :List(Text); - outboundIds @6 :List(Text); - - struct LaneBoundary { - polyLine @0 :PolyLine; - startHeading @1 :Float32; # WRT north - } -} - -# Map tiles -struct TileSummary { - version @0 :Text; - updatedAt @1 :UInt64; # Millis since epoch - - level @2 :UInt8; - x @3 :UInt16; - y @4 :UInt16; -} - -struct MapTile { - summary @0 :TileSummary; - lanes @1 :List(Lane); -} diff --git a/cereal/messaging/__init__.py b/cereal/messaging/__init__.py index 31b9147ee..7aa16cad4 100644 --- a/cereal/messaging/__init__.py +++ b/cereal/messaging/__init__.py @@ -3,12 +3,12 @@ from .messaging_pyx import Context, Poller, SubSocket, PubSocket # pylint: disa from .messaging_pyx import MultiplePublishersError, MessagingError # pylint: disable=no-name-in-module, import-error import capnp -assert MultiplePublishersError -assert MessagingError - from cereal import log from cereal.services import service_list +assert MultiplePublishersError +assert MessagingError + # sec_since_boot is faster, but allow to run standalone too try: from common.realtime import sec_since_boot @@ -73,7 +73,7 @@ def drain_sock(sock, wait_for_one=False): else: dat = sock.receive(non_blocking=True) - if dat is None: # Timeout hit + if dat is None: # Timeout hit break dat = log.Event.from_bytes(dat) @@ -93,7 +93,7 @@ def recv_sock(sock, wait=False): else: rcv = sock.receive(non_blocking=True) - if rcv is None: # Timeout hit + if rcv is None: # Timeout hit break dat = rcv @@ -133,10 +133,10 @@ class SubMaster(): def __init__(self, services, ignore_alive=None, addr="127.0.0.1"): self.poller = Poller() self.frame = -1 - self.updated = {s : False for s in services} - self.rcv_time = {s : 0. for s in services} - self.rcv_frame = {s : 0 for s in services} - self.alive = {s : False for s in services} + self.updated = {s: False for s in services} + self.rcv_time = {s: 0. for s in services} + self.rcv_frame = {s: 0 for s in services} + self.alive = {s: False for s in services} self.sock = {} self.freq = {} self.data = {} diff --git a/cereal/messaging/catch2/catch.hpp b/cereal/messaging/catch2/catch.hpp deleted file mode 100644 index 5feb2a4be..000000000 --- a/cereal/messaging/catch2/catch.hpp +++ /dev/null @@ -1,17075 +0,0 @@ -/* - * Catch v2.9.2 - * Generated: 2019-08-08 13:35:12.279703 - * ---------------------------------------------------------- - * This file has been merged from multiple headers. Please don't edit it directly - * Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved. - * - * Distributed under the Boost Software License, Version 1.0. (See accompanying - * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED -#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED -// start catch.hpp - - -#define CATCH_VERSION_MAJOR 2 -#define CATCH_VERSION_MINOR 9 -#define CATCH_VERSION_PATCH 2 - -#ifdef __clang__ -# pragma clang system_header -#elif defined __GNUC__ -# pragma GCC system_header -#endif - -// start catch_suppress_warnings.h - -#ifdef __clang__ -# ifdef __ICC // icpc defines the __clang__ macro -# pragma warning(push) -# pragma warning(disable: 161 1682) -# else // __ICC -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wpadded" -# pragma clang diagnostic ignored "-Wswitch-enum" -# pragma clang diagnostic ignored "-Wcovered-switch-default" -# endif -#elif defined __GNUC__ - // Because REQUIREs trigger GCC's -Wparentheses, and because still - // supported version of g++ have only buggy support for _Pragmas, - // Wparentheses have to be suppressed globally. -# pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details - -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wunused-variable" -# pragma GCC diagnostic ignored "-Wpadded" -#endif -// end catch_suppress_warnings.h -#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) -# define CATCH_IMPL -# define CATCH_CONFIG_ALL_PARTS -#endif - -// In the impl file, we want to have access to all parts of the headers -// Can also be used to sanely support PCHs -#if defined(CATCH_CONFIG_ALL_PARTS) -# define CATCH_CONFIG_EXTERNAL_INTERFACES -# if defined(CATCH_CONFIG_DISABLE_MATCHERS) -# undef CATCH_CONFIG_DISABLE_MATCHERS -# endif -# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) -# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER -# endif -#endif - -#if !defined(CATCH_CONFIG_IMPL_ONLY) -// start catch_platform.h - -#ifdef __APPLE__ -# include -# if TARGET_OS_OSX == 1 -# define CATCH_PLATFORM_MAC -# elif TARGET_OS_IPHONE == 1 -# define CATCH_PLATFORM_IPHONE -# endif - -#elif defined(linux) || defined(__linux) || defined(__linux__) -# define CATCH_PLATFORM_LINUX - -#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) -# define CATCH_PLATFORM_WINDOWS -#endif - -// end catch_platform.h - -#ifdef CATCH_IMPL -# ifndef CLARA_CONFIG_MAIN -# define CLARA_CONFIG_MAIN_NOT_DEFINED -# define CLARA_CONFIG_MAIN -# endif -#endif - -// start catch_user_interfaces.h - -namespace Catch { - unsigned int rngSeed(); -} - -// end catch_user_interfaces.h -// start catch_tag_alias_autoregistrar.h - -// start catch_common.h - -// start catch_compiler_capabilities.h - -// Detect a number of compiler features - by compiler -// The following features are defined: -// -// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? -// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? -// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? -// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? -// **************** -// Note to maintainers: if new toggles are added please document them -// in configuration.md, too -// **************** - -// In general each macro has a _NO_ form -// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. -// Many features, at point of detection, define an _INTERNAL_ macro, so they -// can be combined, en-mass, with the _NO_ forms later. - -#ifdef __cplusplus - -# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) -# define CATCH_CPP14_OR_GREATER -# endif - -# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) -# define CATCH_CPP17_OR_GREATER -# endif - -#endif - -#if defined(CATCH_CPP17_OR_GREATER) -# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS -#endif - -#ifdef __clang__ - -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ - _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") -# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ - _Pragma( "clang diagnostic pop" ) - -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) -# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic pop" ) - -# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) -# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \ - _Pragma( "clang diagnostic pop" ) - -# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) -# define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \ - _Pragma( "clang diagnostic pop" ) - -#endif // __clang__ - -//////////////////////////////////////////////////////////////////////////////// -// Assume that non-Windows platforms support posix signals by default -#if !defined(CATCH_PLATFORM_WINDOWS) - #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS -#endif - -//////////////////////////////////////////////////////////////////////////////// -// We know some environments not to support full POSIX signals -#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) - #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -#endif - -#ifdef __OS400__ -# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -# define CATCH_CONFIG_COLOUR_NONE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Android somehow still does not support std::to_string -#if defined(__ANDROID__) -# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Not all Windows environments support SEH properly -#if defined(__MINGW32__) -# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH -#endif - -//////////////////////////////////////////////////////////////////////////////// -// PS4 -#if defined(__ORBIS__) -# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Cygwin -#ifdef __CYGWIN__ - -// Required for some versions of Cygwin to declare gettimeofday -// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin -# define _BSD_SOURCE -// some versions of cygwin (most) do not support std::to_string. Use the libstd check. -// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 -# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ - && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) - -# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING - -# endif -#endif // __CYGWIN__ - -//////////////////////////////////////////////////////////////////////////////// -// Visual C++ -#ifdef _MSC_VER - -# if _MSC_VER >= 1900 // Visual Studio 2015 or newer -# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS -# endif - -// Universal Windows platform does not support SEH -// Or console colours (or console at all...) -# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) -# define CATCH_CONFIG_COLOUR_NONE -# else -# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH -# endif - -// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ -// _MSVC_TRADITIONAL == 0 means new conformant preprocessor -// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor -# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) -# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -# endif -#endif // _MSC_VER - -#if defined(_REENTRANT) || defined(_MSC_VER) -// Enable async processing, as -pthread is specified or no additional linking is required -# define CATCH_INTERNAL_CONFIG_USE_ASYNC -#endif // _MSC_VER - -//////////////////////////////////////////////////////////////////////////////// -// Check if we are compiled with -fno-exceptions or equivalent -#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) -# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED -#endif - -//////////////////////////////////////////////////////////////////////////////// -// DJGPP -#ifdef __DJGPP__ -# define CATCH_INTERNAL_CONFIG_NO_WCHAR -#endif // __DJGPP__ - -//////////////////////////////////////////////////////////////////////////////// -// Embarcadero C++Build -#if defined(__BORLANDC__) - #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN -#endif - -//////////////////////////////////////////////////////////////////////////////// - -// Use of __COUNTER__ is suppressed during code analysis in -// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly -// handled by it. -// Otherwise all supported compilers support COUNTER macro, -// but user still might want to turn it off -#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) - #define CATCH_INTERNAL_CONFIG_COUNTER -#endif - -//////////////////////////////////////////////////////////////////////////////// - -// RTX is a special version of Windows that is real time. -// This means that it is detected as Windows, but does not provide -// the same set of capabilities as real Windows does. -#if defined(UNDER_RTSS) || defined(RTX64_BUILD) - #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH - #define CATCH_INTERNAL_CONFIG_NO_ASYNC - #define CATCH_CONFIG_COLOUR_NONE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Check if string_view is available and usable -// The check is split apart to work around v140 (VS2015) preprocessor issue... -#if defined(__has_include) -#if __has_include() && defined(CATCH_CPP17_OR_GREATER) -# define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW -#endif -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Check if optional is available and usable -#if defined(__has_include) -# if __has_include() && defined(CATCH_CPP17_OR_GREATER) -# define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL -# endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) -#endif // __has_include - -//////////////////////////////////////////////////////////////////////////////// -// Check if byte is available and usable -#if defined(__has_include) -# if __has_include() && defined(CATCH_CPP17_OR_GREATER) -# define CATCH_INTERNAL_CONFIG_CPP17_BYTE -# endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) -#endif // __has_include - -//////////////////////////////////////////////////////////////////////////////// -// Check if variant is available and usable -#if defined(__has_include) -# if __has_include() && defined(CATCH_CPP17_OR_GREATER) -# if defined(__clang__) && (__clang_major__ < 8) - // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 - // fix should be in clang 8, workaround in libstdc++ 8.2 -# include -# if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) -# define CATCH_CONFIG_NO_CPP17_VARIANT -# else -# define CATCH_INTERNAL_CONFIG_CPP17_VARIANT -# endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) -# else -# define CATCH_INTERNAL_CONFIG_CPP17_VARIANT -# endif // defined(__clang__) && (__clang_major__ < 8) -# endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) -#endif // __has_include - -#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) -# define CATCH_CONFIG_COUNTER -#endif -#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) -# define CATCH_CONFIG_WINDOWS_SEH -#endif -// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. -#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) -# define CATCH_CONFIG_POSIX_SIGNALS -#endif -// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. -#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) -# define CATCH_CONFIG_WCHAR -#endif - -#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) -# define CATCH_CONFIG_CPP11_TO_STRING -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) -# define CATCH_CONFIG_CPP17_OPTIONAL -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) -# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) -# define CATCH_CONFIG_CPP17_STRING_VIEW -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) -# define CATCH_CONFIG_CPP17_VARIANT -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) -# define CATCH_CONFIG_CPP17_BYTE -#endif - -#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) -# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE -#endif - -#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) -# define CATCH_CONFIG_NEW_CAPTURE -#endif - -#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) -# define CATCH_CONFIG_DISABLE_EXCEPTIONS -#endif - -#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) -# define CATCH_CONFIG_POLYFILL_ISNAN -#endif - -#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) -# define CATCH_CONFIG_USE_ASYNC -#endif - -#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS -#endif - -#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) -#define CATCH_TRY if ((true)) -#define CATCH_CATCH_ALL if ((false)) -#define CATCH_CATCH_ANON(type) if ((false)) -#else -#define CATCH_TRY try -#define CATCH_CATCH_ALL catch (...) -#define CATCH_CATCH_ANON(type) catch (type) -#endif - -#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) -#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#endif - -// end catch_compiler_capabilities.h -#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line -#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) -#ifdef CATCH_CONFIG_COUNTER -# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) -#else -# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) -#endif - -#include -#include -#include - -// We need a dummy global operator<< so we can bring it into Catch namespace later -struct Catch_global_namespace_dummy {}; -std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); - -namespace Catch { - - struct CaseSensitive { enum Choice { - Yes, - No - }; }; - - class NonCopyable { - NonCopyable( NonCopyable const& ) = delete; - NonCopyable( NonCopyable && ) = delete; - NonCopyable& operator = ( NonCopyable const& ) = delete; - NonCopyable& operator = ( NonCopyable && ) = delete; - - protected: - NonCopyable(); - virtual ~NonCopyable(); - }; - - struct SourceLineInfo { - - SourceLineInfo() = delete; - SourceLineInfo( char const* _file, std::size_t _line ) noexcept - : file( _file ), - line( _line ) - {} - - SourceLineInfo( SourceLineInfo const& other ) = default; - SourceLineInfo& operator = ( SourceLineInfo const& ) = default; - SourceLineInfo( SourceLineInfo&& ) noexcept = default; - SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; - - bool empty() const noexcept; - bool operator == ( SourceLineInfo const& other ) const noexcept; - bool operator < ( SourceLineInfo const& other ) const noexcept; - - char const* file; - std::size_t line; - }; - - std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); - - // Bring in operator<< from global namespace into Catch namespace - // This is necessary because the overload of operator<< above makes - // lookup stop at namespace Catch - using ::operator<<; - - // Use this in variadic streaming macros to allow - // >> +StreamEndStop - // as well as - // >> stuff +StreamEndStop - struct StreamEndStop { - std::string operator+() const; - }; - template - T const& operator + ( T const& value, StreamEndStop ) { - return value; - } -} - -#define CATCH_INTERNAL_LINEINFO \ - ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) - -// end catch_common.h -namespace Catch { - - struct RegistrarForTagAliases { - RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); - }; - -} // end namespace Catch - -#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ - CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ - CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS - -// end catch_tag_alias_autoregistrar.h -// start catch_test_registry.h - -// start catch_interfaces_testcase.h - -#include - -namespace Catch { - - class TestSpec; - - struct ITestInvoker { - virtual void invoke () const = 0; - virtual ~ITestInvoker(); - }; - - class TestCase; - struct IConfig; - - struct ITestCaseRegistry { - virtual ~ITestCaseRegistry(); - virtual std::vector const& getAllTests() const = 0; - virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; - }; - - bool isThrowSafe( TestCase const& testCase, IConfig const& config ); - bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); - std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); - std::vector const& getAllTestCasesSorted( IConfig const& config ); - -} - -// end catch_interfaces_testcase.h -// start catch_stringref.h - -#include -#include -#include - -namespace Catch { - - /// A non-owning string class (similar to the forthcoming std::string_view) - /// Note that, because a StringRef may be a substring of another string, - /// it may not be null terminated. c_str() must return a null terminated - /// string, however, and so the StringRef will internally take ownership - /// (taking a copy), if necessary. In theory this ownership is not externally - /// visible - but it does mean (substring) StringRefs should not be shared between - /// threads. - class StringRef { - public: - using size_type = std::size_t; - - private: - friend struct StringRefTestAccess; - - char const* m_start; - size_type m_size; - - char* m_data = nullptr; - - void takeOwnership(); - - static constexpr char const* const s_empty = ""; - - public: // construction/ assignment - StringRef() noexcept - : StringRef( s_empty, 0 ) - {} - - StringRef( StringRef const& other ) noexcept - : m_start( other.m_start ), - m_size( other.m_size ) - {} - - StringRef( StringRef&& other ) noexcept - : m_start( other.m_start ), - m_size( other.m_size ), - m_data( other.m_data ) - { - other.m_data = nullptr; - } - - StringRef( char const* rawChars ) noexcept; - - StringRef( char const* rawChars, size_type size ) noexcept - : m_start( rawChars ), - m_size( size ) - {} - - StringRef( std::string const& stdString ) noexcept - : m_start( stdString.c_str() ), - m_size( stdString.size() ) - {} - - ~StringRef() noexcept { - delete[] m_data; - } - - auto operator = ( StringRef const &other ) noexcept -> StringRef& { - delete[] m_data; - m_data = nullptr; - m_start = other.m_start; - m_size = other.m_size; - return *this; - } - - operator std::string() const; - - void swap( StringRef& other ) noexcept; - - public: // operators - auto operator == ( StringRef const& other ) const noexcept -> bool; - auto operator != ( StringRef const& other ) const noexcept -> bool; - - auto operator[] ( size_type index ) const noexcept -> char; - - public: // named queries - auto empty() const noexcept -> bool { - return m_size == 0; - } - auto size() const noexcept -> size_type { - return m_size; - } - - auto numberOfCharacters() const noexcept -> size_type; - auto c_str() const -> char const*; - - public: // substrings and searches - auto substr( size_type start, size_type size ) const noexcept -> StringRef; - - // Returns the current start pointer. - // Note that the pointer can change when if the StringRef is a substring - auto currentData() const noexcept -> char const*; - - private: // ownership queries - may not be consistent between calls - auto isOwned() const noexcept -> bool; - auto isSubstring() const noexcept -> bool; - }; - - auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string; - auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string; - auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string; - - auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; - auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; - - inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { - return StringRef( rawChars, size ); - } - -} // namespace Catch - -inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { - return Catch::StringRef( rawChars, size ); -} - -// end catch_stringref.h -// start catch_type_traits.hpp - - -#include - -namespace Catch{ - -#ifdef CATCH_CPP17_OR_GREATER - template - inline constexpr auto is_unique = std::true_type{}; - - template - inline constexpr auto is_unique = std::bool_constant< - (!std::is_same_v && ...) && is_unique - >{}; -#else - -template -struct is_unique : std::true_type{}; - -template -struct is_unique : std::integral_constant -::value - && is_unique::value - && is_unique::value ->{}; - -#endif -} - -// end catch_type_traits.hpp -// start catch_preprocessor.hpp - - -#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ -#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) - -#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ -// MSVC needs more evaluations -#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) -#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) -#else -#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) -#endif - -#define CATCH_REC_END(...) -#define CATCH_REC_OUT - -#define CATCH_EMPTY() -#define CATCH_DEFER(id) id CATCH_EMPTY() - -#define CATCH_REC_GET_END2() 0, CATCH_REC_END -#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 -#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 -#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT -#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) -#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) - -#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) - -#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) - -// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, -// and passes userdata as the first parameter to each invocation, -// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) -#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) - -#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) - -#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) -#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ -#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ -#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF -#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) -#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ -#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) -#else -// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF -#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) -#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ -#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) -#endif - -#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ -#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) - -#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) - -#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper()) -#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) -#else -#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) -#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) -#endif - -#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ - CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) - -#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) -#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) -#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) -#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) -#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) -#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) -#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _4, _5, _6) -#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) -#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) -#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) -#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) - -#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N - -#define INTERNAL_CATCH_TYPE_GEN\ - template struct TypeList {};\ - template\ - constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ - \ - template class L1, typename...E1, template class L2, typename...E2> \ - constexpr auto append(L1, L2) noexcept -> L1 { return {}; }\ - template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ - constexpr auto append(L1, L2, Rest...) noexcept -> decltype(append(L1{}, Rest{}...)) { return {}; }\ - template< template class L1, typename...E1, typename...Rest>\ - constexpr auto append(L1, TypeList, Rest...) noexcept -> L1 { return {}; }\ - \ - template< template class Container, template class List, typename...elems>\ - constexpr auto rewrap(List) noexcept -> TypeList> { return {}; }\ - template< template class Container, template class List, class...Elems, typename...Elements>\ - constexpr auto rewrap(List,Elements...) noexcept -> decltype(append(TypeList>{}, rewrap(Elements{}...))) { return {}; }\ - \ - template