diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..ed63b79 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @ZeyadOsama \ No newline at end of file diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..2d272ec --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,22 @@ +# How-to contribute + +Those are the main contributing guidelines for contributing to this project: + +- Verify that your contribution does not embark proprietary code or infringe any copyright of any sort. +- Avoid adding any unnecessary dependencies to the project, especially of those are not easily packaged and installed through `brew` or `apt-get`. +- C/C++ contributions must follow the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html#Run-Time_Type_Information__RTTI_). +- Use [Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) mechanism and please be patient while waiting for reviews. +- Remain polite and civil in all exchanges with the maintainers and other contributors. +- Any issue submitted which does not respect provided template, or lack of information, will be considered as invalid and automatically closed. + +## Get started + +In order to contribute, the safest is to create your [own fork of jsonCPP](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) first. The following set of commands will clone this new repository, create a virtual environment provisioned with the dependencies and run the tests (will take a few minutes): + +```bash +git clone https://github.com//jsonCPP && cd jsonCPP +``` + +You can then make your changes and experiment freely. Once you're done, remember to check that the tests still run. If you've added a new feature, add tests! + +Then finally, you're more than welcome to create a [Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) in **jsonCPP** main repo. We will look at it as soon as possible and eventually integrate your changes in the project. diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 0000000..59b8406 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,49 @@ +--- +NAME: Bug +ABOUT: Report a bug +LABELS: bug, invalid +TITLE: "[Bug] name your bug" +--- + + + +- [ ] I didn't find a similar issue already open. +- [ ] I read the documentation (README & Wiki) +- [ ] My problem is related to jsonCPP only, not a derivative product (such as CMake, or GUI provided by others) + + +## Description + + + +## Step to reproduce + + + +1. Installed using `...` +2. Run as `...` +3. Got `...` error + +## Output + +```bash +Share what your terminal says when you run the script (as well as what you would expect). +``` + +## Environment + + + +| | | +| ----------------- | ------------------------------- | +| OS | Windows / Linux / MacOS / other | +| Installation type | Conda / pip / other | +| RAM available | XGo | +| Hardware spec | GPU / CPU / etc ... | + +## Additional context + + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3ba13e0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/ISSUE_TEMPLATE/discussion.md b/.github/ISSUE_TEMPLATE/discussion.md new file mode 100644 index 0000000..11327b2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/discussion.md @@ -0,0 +1,8 @@ +--- +NAME: Discussion +ABOUT: Ideas sharing or theoretical question solving +LABELS: Question +TITLE: "[Discussion] your question" +--- + + diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md new file mode 100644 index 0000000..5224352 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.md @@ -0,0 +1,14 @@ +--- +NAME: Feature request +ABOUT: Submit idea for new feature +LABELS: feature, enhancement +TITLE: "[Feature] your feature name" +--- + +## Description + + + +## Additional information + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..3172070 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,13 @@ +# [jsonCPP-vX.Y.Z] - + +## Description + +A few sentences describing the overall goals of the pull request's commits. + +## How this patch was tested + +You tested it, right? + +## Documentation link and external references + +Please provide any info that may help us better understand your code. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c6f21bf --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,32 @@ +name: CI + +on: [ push ] + +jobs: + + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ ubuntu-latest, macos-latest ] + configs: [ Release, Debug ] + + steps: + - name: Checkout + uses: actions/checkout@v2.0.0 + + - name: Build + uses: nicledomaS/cmake_build_action@v1.3 + with: + config: ${{ matrix.configs }} + cmake_args: -DjsonCPP_BUILD_EXAMPLES=ON; + + - name: Test + uses: nicledomaS/cmake_build_action@v1.3 + with: + config: ${{ matrix.configs }} + cmake_args: -DjsonCPP_BUILD_TESTS=ON; + + - name: Lint + uses: deep5050/cppcheck-action@v2.0.0 + continue-on-error: true \ No newline at end of file diff --git a/.gitignore b/.gitignore index b61a8fc..6537da5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,70 @@ -### C++ ### +### C ### # Prerequisites *.d -# Compiled Object files -*.slo -*.lo +# Object files *.o +*.ko *.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp # Precompiled Headers *.gch *.pch -# Compiled Dynamic libraries +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll *.so +*.so.* *.dylib -*.dll + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +### C++ ### +# Prerequisites + +# Compiled Object files +*.slo + +# Precompiled Headers + +# Linker files + +# Debugger Files + +# Compiled Dynamic libraries # Fortran module files *.mod @@ -23,16 +72,10 @@ # Compiled Static libraries *.lai -*.la -*.a -*.lib # Executables -*.exe -*.out -*.app -### CLion ### +### CLion+all ### # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 @@ -105,32 +148,40 @@ fabric.properties # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser -### CLion Patch ### -# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 +### CLion+all Patch ### +# Ignores the whole .idea folder and all .iml files +# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 -# *.iml -# modules.xml -# .idea/misc.xml -# *.ipr +.idea/ + +# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 + +*.iml +modules.xml +.idea/misc.xml +*.ipr # Sonarlint plugin -# https://plugins.jetbrains.com/plugin/7973-sonarlint -.idea/**/sonarlint/ - -# SonarQube Plugin -# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin -.idea/**/sonarIssues.xml - -# Markdown Navigator plugin -# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced -.idea/**/markdown-navigator.xml -.idea/**/markdown-navigator-enh.xml -.idea/**/markdown-navigator/ - -# Cache file creation bug -# See https://youtrack.jetbrains.com/issue/JBR-2257 -.idea/$CACHE_FILE$ - -# CodeStream plugin -# https://plugins.jetbrains.com/plugin/12206-codestream -.idea/codestream.xml +.idea/sonarlint + +### CMake ### +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps +CMakeUserPresets.json + +### CMake Patch ### +# External projects +*-prefix/ + +### Project Dependent ### +/log +*.log diff --git a/CHANGELOG.rst b/CHANGELOG.rst new file mode 100644 index 0000000..d051871 --- /dev/null +++ b/CHANGELOG.rst @@ -0,0 +1,13 @@ +============================================== +jsonCPP Release Notes +============================================== + +v.1.0.0 +======= + +**Added**: + +* Supports *.json file parsing +* Supports folder containing multiple *.json files parsing +* Uses C++11 standard. +* Uses CMake 3.5 standard. \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 1426a26..f44ee6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,16 +1,31 @@ -cmake_minimum_required(VERSION 3.4) -project(JSON-Parser) +# Set minimum cmake version +cmake_minimum_required(VERSION 3.5 FATAL_ERROR) +cmake_policy(SET CMP0048 NEW) -set(CMAKE_CXX_STANDARD 14) +# Project settings. +project(JSON-CPP VERSION 1.0.0) + +# Set C++ standard to c++11. +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) add_definitions(-DDATA_PATH="./examples/data/") -add_subdirectory(json) -include_directories(json/include) +include_directories(prerequisites) +include_directories(include) + +add_subdirectory(src) + +option(jsonCPP_BUILD_EXAMPLES "Build the example of jsonCPP." OFF) +if (jsonCPP_BUILD_EXAMPLES) + add_subdirectory(examples) +endif () -option(JSON_BUILD_EXAMPLE "Build the example of CLogger." OFF) -if (JSON_BUILD_EXAMPLE) - # add the example executable, linked with the JSON library - add_executable(JSON_Example examples/main.cpp) - target_link_libraries(JSON_Example JSON ${SYSTEM_LIBRARIES}) +option(jsonCPP_BUILD_TESTS "Build the tests of jsonCPP." OFF) +if (jsonCPP_BUILD_TESTS) + add_subdirectory(tests) + include(CTest) + add_test(NAME System-Tests + COMMAND system-tests + ) endif () \ No newline at end of file diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt new file mode 100644 index 0000000..6cd34f6 --- /dev/null +++ b/CONTRIBUTORS.txt @@ -0,0 +1,9 @@ +# This file contains a list of people who've made non-trivial +# contribution to the jsonCPP project. +# +# People who commit code to the project are encouraged to add their names +# here. +# +# Please keep the list sorted by first names. + +Zeyad Osama \ No newline at end of file diff --git a/README.md b/README.md index 6f835c4..d43a121 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,18 @@ # jsonCPP -

- stable - contributions-welcome-orange -

+[![CI Actions Status](https://github.com/ZeyadOsama/jsonCPP/workflows/CI/badge.svg)](https://github.com/ZeyadOsama/jsonCPP/actions) +stable +contributions-welcome-orange + +## About C++ JSON **```(*.json)```** Parser. ## Usage In your **```CMakeLists.txt```** file add these lines + ```cmake add_subdirectory(json) -include_directories(json/include) +include_directories(include) ``` Then add this header in the file you'd like to have your parser at @@ -36,4 +38,19 @@ string json_file_path_1 = "" json::Value val = Parser::ParseFile(json_file_path_1); ``` +## Versioning +When installing jsonCPP, require it's version. For us, this is what ```major.minor.patch``` means: + +- ```major``` - **MAJOR breaking changes**; includes major new features, major changes in how the whole system works, and complete rewrites; it allows us to _considerably_ improve the product, and add features that were previously impossible. +- ```minor``` - **MINOR breaking changes**; it allows us to add big new features. +- ```patch``` - **NO breaking changes**; includes bug fixes and non-breaking new features. + +## Changelog +For all-time versions, please see the [CHANGELOG](CHANGELOG.rst) file. + + +## License +This project is licensed under the MIT License - see the [LICENSE](LICENSE.txt) file for details + + diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..eb10e57 --- /dev/null +++ b/TODO.md @@ -0,0 +1,12 @@ +# TODO + +This file should keep track of what to revisit, tasks to be kept into consideration and in progress tasks. + +### Todo + +- [ ] Add tests. +- [ ] Add documentations. +- [ ] Add Github Pages. +- [ ] Add packaging support. +- [ ] Add a basic thread-safety security. +- [ ] Add Valgrind to CI/CD to ensure no memory leaks diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..a861422 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,3 @@ +# add the example executable, linked with the jsonCPP library +add_executable(jsonCPP_Example end-to-end/main.cpp) +target_link_libraries(jsonCPP_Example jsonCPP ${SYSTEM_LIBRARIES}) \ No newline at end of file diff --git a/examples/data/dummy.json b/examples/end-to-end/data/dummy.json similarity index 59% rename from examples/data/dummy.json rename to examples/end-to-end/data/dummy.json index aa8abeb..1a86d1c 100644 --- a/examples/data/dummy.json +++ b/examples/end-to-end/data/dummy.json @@ -44,19 +44,5 @@ { "control_chars": "here is \\n: \nand it is tab: \t!\nsupports \" and other control chars\n" } - ], - "physics": "acoustic", - "approximation": "isotropic", - "equation-order": "second", - "grid-sampling": "uniform", - "technology": "openmp", - "model-handler": "homogenous", - "source-injector": "ricker", - "boundary-manager": "cpml", - "boundary-manager.use-top-layer": "yes", - "trace-writer": "binary", - "modelling-configuration-parser": "text", - "trace-file": "data/shot.trace", - "modelling-configuration-file": "data/modelling.txt", - "models-list": "data/models.txt" + ] } \ No newline at end of file diff --git a/examples/main.cpp b/examples/end-to-end/main.cpp similarity index 93% rename from examples/main.cpp rename to examples/end-to-end/main.cpp index e00ab56..931c7ee 100644 --- a/examples/main.cpp +++ b/examples/end-to-end/main.cpp @@ -1,6 +1,6 @@ #include -#include +#include using namespace std; using namespace json; diff --git a/include/json/common/datatypes/JTypes.h b/include/json/common/datatypes/JTypes.h new file mode 100644 index 0000000..96251cd --- /dev/null +++ b/include/json/common/datatypes/JTypes.h @@ -0,0 +1,20 @@ +// +// Created by zeyad-osama on 16/08/2020. +// + +#pragma once + +namespace json { + namespace types { + + enum JSON_TYPE { + J_STRING, + J_NUMBER, + J_BOOL, + J_NULL, + J_UNKNOWN, + J_OBJECT, + J_ARRAY + }; + } //namespace types +} //namespace json diff --git a/include/json/common/datatypes/TTypes.h b/include/json/common/datatypes/TTypes.h new file mode 100644 index 0000000..3d7ab3e --- /dev/null +++ b/include/json/common/datatypes/TTypes.h @@ -0,0 +1,24 @@ +// +// Created by zeyad-osama on 16/08/2020. +// + +#pragma once + +namespace json { + namespace types { + + enum TOKEN_TYPE { + T_STRING, + T_NUMBER, + T_BOOL, + T_NULL, + T_UNKNOWN, + T_CURL_OPEN, + T_CURL_CLOSE, + T_BRACKET_OPEN, + T_BRACKET_CLOSE, + T_COMMA, + T_COLON + }; + } //namespace types +} //namespace json diff --git a/include/json/common/datatypes/Types.h b/include/json/common/datatypes/Types.h new file mode 100644 index 0000000..4e657a8 --- /dev/null +++ b/include/json/common/datatypes/Types.h @@ -0,0 +1,8 @@ +// +// Created by zeyad-osama on 03/06/2020. +// + +#pragma once + +#include +#include diff --git a/include/json/common/dataunits/Token.h b/include/json/common/dataunits/Token.h new file mode 100644 index 0000000..b813443 --- /dev/null +++ b/include/json/common/dataunits/Token.h @@ -0,0 +1,34 @@ +// +// Created by zeyad-osama on 03/06/2020. +// + +#pragma once + +#include + +#include +#include + +namespace json { + namespace dataunits { + + class Token { + + public: + explicit Token(std::string value = "", types::TOKEN_TYPE type = types::T_UNKNOWN) + : mValue(std::move(value)), mType(type) {} + + inline std::string GetValue() { + return mValue; + } + + inline types::TOKEN_TYPE GetType() { + return mType; + } + + private: + std::string mValue; + types::TOKEN_TYPE mType; + }; + } //namespace dataunits +} //namespace json \ No newline at end of file diff --git a/json/include/Base/Value.h b/include/json/common/dataunits/Value.h similarity index 89% rename from json/include/Base/Value.h rename to include/json/common/dataunits/Value.h index 1d07043..a6a64d5 100644 --- a/json/include/Base/Value.h +++ b/include/json/common/dataunits/Value.h @@ -4,7 +4,7 @@ #pragma once -#include +#include #include #include @@ -19,7 +19,7 @@ namespace json { typedef std::pair Property; public: - explicit Value(JSON_TYPE= J_UNKNOWN); + explicit Value(types::JSON_TYPE= types::J_UNKNOWN); /** * @brief Retrieves the object at the passed index. Useful for Values @@ -71,7 +71,7 @@ namespace json { * @return Type of Value object */ - inline JSON_TYPE Type() { + inline types::JSON_TYPE Type() { return mType; } @@ -86,7 +86,7 @@ namespace json { std::string ToString(); - inline void SetType(JSON_TYPE aType) { + inline void SetType(types::JSON_TYPE aType) { mType = aType; } @@ -96,9 +96,9 @@ namespace json { private: std::string mValue; - JSON_TYPE mType; + types::JSON_TYPE mType; std::vector mProperties; std::map mMapValues; std::vector mValues; }; -} \ No newline at end of file +} //namespace json \ No newline at end of file diff --git a/include/json/json.h b/include/json/json.h new file mode 100644 index 0000000..3be29a4 --- /dev/null +++ b/include/json/json.h @@ -0,0 +1,9 @@ +// +// Created by zeyad-osama on 26/07/2020. +// + +#pragma once + +#include +#include +#include diff --git a/json/include/Utils/LibVars/Extension.h b/include/json/libvars/Extension.h similarity index 100% rename from json/include/Utils/LibVars/Extension.h rename to include/json/libvars/Extension.h diff --git a/include/json/libvars/Version.h b/include/json/libvars/Version.h new file mode 100644 index 0000000..a3daa75 --- /dev/null +++ b/include/json/libvars/Version.h @@ -0,0 +1,16 @@ +// +// Created by zeyad-osama on 09/01/2021. +// + +#ifndef JSON_CPP_LIB_VARS_VERSION_H +#define JSON_CPP_LIB_VARS_VERSION_H + +#define JSON_CPP_VERSION_MAJOR 1 +#define JSON_CPP_VERSION_MINOR 0 +#define JSON_CPP_VERSION_PATCH 0 + +#define JSON_CPP_VERSION \ + (((JSON_CPP_VERSION_MAJOR)*10000000) + ((JSON_CPP_VERSION_MINOR)*100000) \ + + (JSON_CPP_VERSION_PATCH)) + +#endif //JSON_CPP_LIB_VARS_VERSION_H \ No newline at end of file diff --git a/json/include/Base/Parser.h b/include/json/parsers/Parser.h similarity index 78% rename from json/include/Base/Parser.h rename to include/json/parsers/Parser.h index e22ef4d..5659cdb 100644 --- a/json/include/Base/Parser.h +++ b/include/json/parsers/Parser.h @@ -4,8 +4,8 @@ #pragma once -#include -#include +#include +#include namespace json { @@ -38,8 +38,8 @@ namespace json { static Value ParseMultiple(const std::vector &file_paths); private: - static std::vector Tokenize(std::string source); + static std::vector Tokenize(std::string source); - static Value ParseJSON(std::vector token_vector, int i, int &r); + static Value ParseJSON(std::vector token_vector, int i, int &r); }; -} \ No newline at end of file +} //namespace json \ No newline at end of file diff --git a/include/json/utils/Utils.h b/include/json/utils/Utils.h new file mode 100644 index 0000000..379000c --- /dev/null +++ b/include/json/utils/Utils.h @@ -0,0 +1,20 @@ +// +// Created by zeyad-osama on 16/08/2020. +// + +#pragma once + +#include + +namespace json { + namespace utils { + + int next_whitespace(const std::string &source, int i); + + int skip_whitespaces(const std::string &source, int i); + + std::string deserialize(const std::string &ref); + + std::string add_space(int len); + } //namespace utils +} //namespace json \ No newline at end of file diff --git a/json/CMakeLists.txt b/json/CMakeLists.txt deleted file mode 100644 index b682197..0000000 --- a/json/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# JSON Library CMakeLists.txt - -include_directories(include) -add_library( - JSON - SHARED - - src/Base/Parser.cpp - src/Base/Value.cpp - src/Utils/Utils.cpp -) \ No newline at end of file diff --git a/json/include/Base/Token.h b/json/include/Base/Token.h deleted file mode 100644 index 82fd5f4..0000000 --- a/json/include/Base/Token.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// Created by zeyad-osama on 03/06/2020. -// - -#pragma once - -#include - -#include -#include - -namespace json { - - class Token { - - public: - explicit Token(std::string value = "", TOKEN_TYPE type = T_UNKNOWN) - : mValue(std::move(value)), mType(type) {} - - inline std::string GetValue() { - return mValue; - } - - inline TOKEN_TYPE GetType() { - return mType; - } - - private: - std::string mValue; - TOKEN_TYPE mType; - }; -} \ No newline at end of file diff --git a/json/include/Utils/DataTypes/JTypes.h b/json/include/Utils/DataTypes/JTypes.h deleted file mode 100644 index cdfff50..0000000 --- a/json/include/Utils/DataTypes/JTypes.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// Created by zeyad-osama on 16/08/2020. -// - -#pragma once - -namespace json { - - enum JSON_TYPE { - J_STRING, - J_NUMBER, - J_BOOL, - J_NULL, - J_UNKNOWN, - J_OBJECT, - J_ARRAY - }; -} diff --git a/json/include/Utils/DataTypes/TTypes.h b/json/include/Utils/DataTypes/TTypes.h deleted file mode 100644 index 48336d6..0000000 --- a/json/include/Utils/DataTypes/TTypes.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// Created by zeyad-osama on 16/08/2020. -// - -#pragma once - -namespace json { - - enum TOKEN_TYPE { - T_STRING, - T_NUMBER, - T_BOOL, - T_NULL, - T_UNKNOWN, - T_CURL_OPEN, - T_CURL_CLOSE, - T_BRACKET_OPEN, - T_BRACKET_CLOSE, - T_COMMA, - T_COLON - }; -} diff --git a/json/include/Utils/DataTypes/Types.h b/json/include/Utils/DataTypes/Types.h deleted file mode 100644 index a8e380f..0000000 --- a/json/include/Utils/DataTypes/Types.h +++ /dev/null @@ -1,8 +0,0 @@ -// -// Created by zeyad-osama on 03/06/2020. -// - -#pragma once - -#include -#include diff --git a/json/include/Utils/Utils.h b/json/include/Utils/Utils.h deleted file mode 100644 index 9eea2b7..0000000 --- a/json/include/Utils/Utils.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// Created by zeyad-osama on 16/08/2020. -// - -#pragma once - -#include - -namespace json { - - int next_whitespace(const std::string &source, int i); - - int skip_whitespaces(const std::string &source, int i); - - std::string deserialize(const std::string &ref); - - std::string add_space(int len); -} \ No newline at end of file diff --git a/json/include/json.h b/json/include/json.h deleted file mode 100644 index bed365f..0000000 --- a/json/include/json.h +++ /dev/null @@ -1,9 +0,0 @@ -// -// Created by zeyad-osama on 26/07/2020. -// - -#pragma once - -#include -#include -#include diff --git a/json/src/Base/Parser.cpp b/json/src/Base/Parser.cpp deleted file mode 100644 index b98efc0..0000000 --- a/json/src/Base/Parser.cpp +++ /dev/null @@ -1,187 +0,0 @@ -// -// Created by zeyad-osama on 03/06/2020. -// - -#include -#include -#include - -#include - -using namespace std; - -namespace json { - - vector Parser::Tokenize(string source) { - source += " "; - vector tokens; - int index = skip_whitespaces(source, 0); - while (index >= 0) { - int next = next_whitespace(source, index); - string str = source.substr(index, next - index); - - size_t k = 0; - while (k < str.length()) { - if (str[k] == '"') { - size_t tmp_k = k + 1; - while (tmp_k < str.length() && (str[tmp_k] != '"' || str[tmp_k - 1] == '\\')) tmp_k++; - tokens.emplace_back(str.substr(k + 1, tmp_k - k - 1), T_STRING); - k = tmp_k + 1; - continue; - } - if (str[k] == '\'') { - size_t tmp_k = k + 1; - while (tmp_k < str.length() && (str[tmp_k] != '\'' || str[tmp_k - 1] == '\\')) tmp_k++; - tokens.emplace_back(str.substr(k + 1, tmp_k - k - 1), T_STRING); - k = tmp_k + 1; - continue; - } - if (str[k] == ',') { - tokens.emplace_back(",", T_COMMA); - k++; - continue; - } - if (str[k] == 't' && k + 3 < str.length() && str.substr(k, 4) == "true") { - tokens.emplace_back("true", T_BOOL); - k += 4; - continue; - } - if (str[k] == 'f' && k + 4 < str.length() && str.substr(k, 5) == "false") { - tokens.emplace_back("false", T_BOOL); - k += 5; - continue; - } - if (str[k] == 'n' && k + 3 < str.length() && str.substr(k, 4) == "null") { - tokens.emplace_back("null", T_NULL); - k += 4; - continue; - } - if (str[k] == '}') { - tokens.emplace_back("}", T_CURL_CLOSE); - k++; - continue; - } - if (str[k] == '{') { - tokens.emplace_back("{", T_CURL_OPEN); - k++; - continue; - } - if (str[k] == ']') { - tokens.emplace_back("]", T_BRACKET_CLOSE); - k++; - continue; - } - if (str[k] == '[') { - tokens.emplace_back("[", T_BRACKET_OPEN); - k++; - continue; - } - if (str[k] == ':') { - tokens.emplace_back(":", T_COLON); - k++; - continue; - } - if (str[k] == '-' || (str[k] <= '9' && str[k] >= '0')) { - size_t tmp_k = k; - if (str[tmp_k] == '-') tmp_k++; - while (tmp_k < str.size() && ((str[tmp_k] <= '9' && str[tmp_k] >= '0') || str[tmp_k] == '.')) - tmp_k++; - tokens.emplace_back(str.substr(k, tmp_k - k), T_NUMBER); - k = tmp_k; - continue; - } - tokens.emplace_back(str.substr(k), T_UNKNOWN); - k = str.length(); - } - - index = skip_whitespaces(source, next); - } - return tokens; - } - - Value Parser::ParseJSON(vector token_vector, int i, int &r) { - Value current; - if (token_vector[i].GetType() == T_CURL_OPEN) { - current.SetType(J_OBJECT); - int k = i + 1; - while (token_vector[k].GetType() != T_CURL_CLOSE) { - string key = token_vector[k].GetValue(); - k += 2; // k+1 should be ':' - int j = k; - Value val = ParseJSON(token_vector, k, j); - current.AddProperty(key, val); - k = j; - if (token_vector[k].GetType() == T_COMMA) k++; - } - r = k + 1; - return current; - } - if (token_vector[i].GetType() == T_BRACKET_OPEN) { - current.SetType(J_ARRAY); - int k = i + 1; - while (token_vector[k].GetType() != T_BRACKET_CLOSE) { - int j = k; - Value vv = ParseJSON(token_vector, k, j); - current.AddElement(vv); - k = j; - if (token_vector[k].GetType() == T_COMMA) k++; - } - r = k + 1; - return current; - } - if (token_vector[i].GetType() == T_NUMBER) { - current.SetType(J_NUMBER); - current.SetValue(token_vector[i].GetValue()); - r = i + 1; - return current; - } - if (token_vector[i].GetType() == T_STRING) { - current.SetType(J_STRING); - current.SetValue(token_vector[i].GetValue()); - r = i + 1; - return current; - } - if (token_vector[i].GetType() == T_BOOL) { - current.SetType(J_BOOL); - current.SetValue(token_vector[i].GetValue()); - r = i + 1; - return current; - } - if (token_vector[i].GetType() == T_NULL) { - current.SetType(J_NULL); - current.SetValue("null"); - r = i + 1; - return current; - } - return current; - } - - Value Parser::ParseString(const string &str) { - int k; - return ParseJSON(Tokenize(str), 0, k); - } - - Value Parser::ParseFile(const string &file_path) { - ifstream in(file_path.c_str()); - string str; - string tmp; - while (getline(in, tmp)) str += tmp; - in.close(); - return ParseString(str); - } - - Value Parser::ParseMultiple(const vector &file_paths) { - string total; - for (const string &file:file_paths) { - string str; - ifstream in(file.c_str()); - string tmp; - while (getline(in, tmp)) str += tmp; - in.close(); - str.erase(0, 1); - str.erase(str.size() - 1); - total += str; - } - return ParseString("{" + total + "}"); - } -} \ No newline at end of file diff --git a/json/src/Base/Value.cpp b/json/src/Base/Value.cpp deleted file mode 100644 index b8f3386..0000000 --- a/json/src/Base/Value.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// -// Created by zeyad-osama on 03/06/2020. -// - -#include -#include - -#include -#include -#include -#include - -using namespace std; - -namespace json { - - Value::Value(JSON_TYPE t) { - mType = t; - } - - Value Value::operator[](int index) { - if (mType == J_ARRAY) - return mValues[index]; - if (mType == J_OBJECT) - return mProperties[index].second; - return Value(); - } - - Value Value::operator[](const string &key) { - if (mMapValues.find(key) == mMapValues.end()) - return Value(); - return mProperties[mMapValues[key]].second; - } - - void Value::AddProperty(const string &key, const Value &aValue) { - mMapValues[key] = mProperties.size(); - mProperties.emplace_back(key, aValue); - } - - void Value::AddElement(const Value &aValue) { - mValues.push_back(aValue); - } - - string Value::AsString() { - return deserialize(mValue); - } - - int Value::AsInteger() { - stringstream ss; - ss << mValue; - int k; - ss >> k; - return k; - } - - long Value::AsLong() { - stringstream ss; - ss << mValue; - long k; - ss >> k; - return k; - } - - double Value::AsDouble() { - stringstream ss; - ss << mValue; - double k; - ss >> k; - return k; - } - - float Value::AsFloat() { - stringstream ss; - ss << mValue; - float k; - ss >> k; - return k; - } - - bool Value::AsBoolean() { - return mValue == "true"; - } - - int Value::Size() { - if (mType == J_ARRAY) - return (int) mValues.size(); - if (mType == J_OBJECT) - return (int) mProperties.size(); - return 0; - } - - string Value::ToString() { - return ToStringSpace(); - } - - string Value::ToStringSpace(int space) { - if (mType == J_STRING) return string("\"") + mValue + string("\""); - if (mType == J_NUMBER) return mValue; - if (mType == J_BOOL) return mValue; - if (mType == J_NULL) return "null"; - if (mType == J_OBJECT) { - string s = string("{\n"); - for (size_t i = 0; i < mProperties.size(); i++) { - s += add_space(space) + string("\"") + mProperties[i].first + string("\": ") + - mProperties[i].second.ToStringSpace(space + 1) + string(i == mProperties.size() - 1 ? "" : ",") + - string("\n"); - } - s += add_space(space - 1) + string("}"); - return s; - } - if (mType == J_ARRAY) { - string s = "["; - for (size_t i = 0; i < mValues.size(); i++) { - if (i) s += ", "; - s += mValues[i].ToStringSpace(space + 1); - } - s += "]"; - return s; - } - return "##"; - } -} \ No newline at end of file diff --git a/json/src/Utils/Utils.cpp b/json/src/Utils/Utils.cpp deleted file mode 100644 index 02c1457..0000000 --- a/json/src/Utils/Utils.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// -// Created by zeyad-osama on 16/08/2020. -// - -#include - -using namespace std; - -namespace json { - - int next_whitespace(const string &source, int i) { - while (i < (int) source.length()) { - if (source[i] == '"') { - i++; - while (i < (int) source.length() && (source[i] != '"' || source[i - 1] == '\\')) i++; - } - if (source[i] == '\'') { - i++; - while (i < (int) source.length() && (source[i] != '\'' || source[i - 1] == '\\')) i++; - } - if (isspace(source[i])) return i; - i++; - } - return (int) source.length(); - } - - int skip_whitespaces(const string &source, int i) { - while (i < (int) source.length()) { - if (!isspace(source[i])) return i; - i++; - } - return -1; - } - - string deserialize(const string &ref) { - string out; - for (size_t i = 0; i < ref.length(); i++) { - if (ref[i] == '\\' && i + 1 < ref.length()) { - int plus = 2; - if (ref[i + 1] == '\"') - out += '"'; - else if (ref[i + 1] == '\\') - out += '\\'; - else if (ref[i + 1] == '/') - out += '/'; - else if (ref[i + 1] == 'b') - out += '\b'; - else if (ref[i + 1] == 'f') - out += '\f'; - else if (ref[i + 1] == 'n') - out += '\n'; - else if (ref[i + 1] == 'r') - out += '\r'; - else if (ref[i + 1] == 't') - out += '\t'; - else if (ref[i + 1] == 'u' && i + 5 < ref.length()) { - unsigned long long v = 0; - for (int j = 0; j < 4; j++) { - v *= 16; - if (ref[i + 2 + j] <= '9' && ref[i + 2 + j] >= '0') v += ref[i + 2 + j] - '0'; - if (ref[i + 2 + j] <= 'f' && ref[i + 2 + j] >= 'a') v += ref[i + 2 + j] - 'a' + 10; - } - out += (char) v; - plus = 6; - } - i += plus - 1; - continue; - } - out += ref[i]; - } - return out; - } - - string add_space(int len) { - string s; - while (len--) s += " "; - return s; - } -} diff --git a/prerequisites/catch/catch.hpp b/prerequisites/catch/catch.hpp new file mode 100644 index 0000000..abdb7b6 --- /dev/null +++ b/prerequisites/catch/catch.hpp @@ -0,0 +1,18123 @@ +/* + * Catch v2.13.2 + * Generated: 2020-10-07 11:32:53.302017 + * ---------------------------------------------------------- + * This file has been merged from multiple headers. Please don't edit it directly + * Copyright (c) 2020 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 13 +#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 + +// We have to avoid both ICC and Clang, because they try to mask themselves +// as gcc, and we want only GCC in this block +#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) + +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) + +#endif + +#if defined(__clang__) + +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) + +// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug +// which results in calls to destructors being emitted for each temporary, +// without a matching initialization. In practice, this can result in something +// like `std::string::~string` being called on an uninitialized value. +// +// For example, this code will likely segfault under IBM XL: +// ``` +// REQUIRE(std::string("12") + "34" == "1234") +// ``` +// +// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. +# if !defined(__ibmxl__) && !defined(__CUDACC__) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ +# endif + +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ + _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") + +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) + +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) + +#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 +# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE +#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++ +#if defined(_MSC_VER) + +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) + +// 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(__clang__) // Handle Clang masquerading for msvc +# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) +# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +# endif // MSVC_TRADITIONAL +# endif // __clang__ + +#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 + +#if !defined(_GLIBCXX_USE_C99_MATH_TR1) +#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Various stdlib support checks that require __has_include +#if defined(__has_include) +// Check if string_view is available and usable +#if __has_include() && defined(CATCH_CPP17_OR_GREATER) +# define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW +#endif + +// Check if optional is available and usable +# if __has_include() && defined(CATCH_CPP17_OR_GREATER) +# define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL +# endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + +// Check if byte is available and usable +# if __has_include() && defined(CATCH_CPP17_OR_GREATER) + +# include + +# if __cpp_lib_byte > 0 +# define CATCH_INTERNAL_CONFIG_CPP17_BYTE +# endif +# endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + +// Check if variant is available and usable +# 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 // defined(__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_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_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) +# define CATCH_CONFIG_ANDROID_LOGWRITE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) +# define CATCH_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Even if we do not think the compiler has that warning, we still have +// to provide a macro that can be used by the code. +#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS +#endif + +// The goal of this macro is to avoid evaluation of the arguments, but +// still have the compiler warn on problems inside... +#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) +#endif + +#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#elif defined(__clang__) && (__clang_major__ < 5) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_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 { return file[0] == '\0'; } + + 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_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION + +// 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 +#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. + class StringRef { + public: + using size_type = std::size_t; + using const_iterator = const char *; + + private: + static constexpr char const *const s_empty = ""; + + char const *m_start = s_empty; + size_type m_size = 0; + + public: // construction + constexpr StringRef() noexcept = default; + + StringRef(char const *rawChars) noexcept; + + constexpr 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()) {} + + explicit operator std::string() const { + return std::string(m_start, m_size); + } + + public: // operators + auto operator==(StringRef const &other) const noexcept -> bool; + + auto operator!=(StringRef const &other) const noexcept -> bool { + return !(*this == other); + } + + auto operator[](size_type index) const noexcept -> char { + assert(index < m_size); + return m_start[index]; + } + + public: // named queries + constexpr auto empty() const noexcept -> bool { + return m_size == 0; + } + + constexpr auto size() const noexcept -> size_type { + return m_size; + } + + // Returns the current start pointer. If the StringRef is not + // null-terminated, throws std::domain_exception + auto c_str() const -> char const *; + + public: // substrings and searches + // Returns a substring of [start, start + length). + // If start + length > size(), then the substring is [start, size()). + // If start > size(), then the substring is empty. + auto substr(size_type start, size_type length) const noexcept -> StringRef; + + // Returns the current start pointer. May not be null-terminated. + auto data() const noexcept -> char const *; + + constexpr auto isNullTerminated() const noexcept -> bool { + return m_start[m_size] == '\0'; + } + + public: // iterators + constexpr const_iterator begin() const { return m_start; } + + constexpr const_iterator end() const { return m_start + m_size; } + }; + + auto operator+=(std::string &lhs, StringRef const &sr) -> std::string &; + + auto operator<<(std::ostream &os, StringRef const &sr) -> std::ostream &; + + constexpr auto operator "" _sr(char const *rawChars, std::size_t size) noexcept -> StringRef { + return StringRef(rawChars, size); + } +} // namespace Catch + +constexpr 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_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, _3, _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...> struct TemplateTypeList{};\ + template class...Cs>\ + constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ + template\ + struct append;\ + template\ + struct rewrap;\ + template class, typename...>\ + struct create;\ + template class, typename>\ + struct convert;\ + \ + template \ + struct append { using type = T; };\ + template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ + struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ + template< template class L1, typename...E1, typename...Rest>\ + struct append, TypeList, Rest...> { using type = L1; };\ + \ + template< template class Container, template class List, typename...elems>\ + struct rewrap, List> { using type = TypeList>; };\ + template< template class Container, template class List, class...Elems, typename...Elements>\ + struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ + \ + template