diff --git a/.bazelrc b/.bazelrc
deleted file mode 100644
index e69de29..0000000
diff --git a/.clwb/.bazelproject b/.clwb/.bazelproject
deleted file mode 100644
index cb6ab22..0000000
--- a/.clwb/.bazelproject
+++ /dev/null
@@ -1,17 +0,0 @@
-directories:
- # Add the directories you want added as source here
- # By default, we've added your entire workspace ('.')
- .
-
-# Automatically includes all relevant targets under the 'directories' above
-derive_targets_from_directories: true
-
-targets:
- # If source code isn't resolving, add additional targets that compile it here
-
-additional_languages:
- # Uncomment any additional languages you want supported
- # dart
- # javascript
- # python
- # typescript
diff --git a/.clwb/.blaze/modules/.project-data-dir.iml b/.clwb/.blaze/modules/.project-data-dir.iml
deleted file mode 100644
index 1ed44f8..0000000
--- a/.clwb/.blaze/modules/.project-data-dir.iml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.clwb/.blaze/modules/.workspace.iml b/.clwb/.blaze/modules/.workspace.iml
deleted file mode 100644
index 6e20532..0000000
--- a/.clwb/.blaze/modules/.workspace.iml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.clwb/.idea/.gitignore b/.clwb/.idea/.gitignore
deleted file mode 100644
index 13566b8..0000000
--- a/.clwb/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.clwb/.idea/.name b/.clwb/.idea/.name
deleted file mode 100644
index 709962e..0000000
--- a/.clwb/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-umbra
\ No newline at end of file
diff --git a/.clwb/.idea/modules.xml b/.clwb/.idea/modules.xml
deleted file mode 100644
index 6e46a2e..0000000
--- a/.clwb/.idea/modules.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.clwb/.idea/vcs.xml b/.clwb/.idea/vcs.xml
deleted file mode 100644
index 6c0b863..0000000
--- a/.clwb/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index b87b98f..9f8da50 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,7 +4,7 @@ obj/
riderModule.iml
/_ReSharper.Caches/
-*.user
-bazel-*/
-test-results
\ No newline at end of file
+test-results
+/cmake-build-vs-debug/
+/.idea/
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..4905df2
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,40 @@
+cmake_minimum_required(VERSION 3.22)
+
+Include(FetchContent)
+
+# Fetch SDL for the runtime
+FetchContent_Declare(
+ SDL2
+ URL https://www.libsdl.org/release/SDL2-devel-2.0.22-VC.zip
+)
+FetchContent_MakeAvailable(SDL2)
+set(SDL2_PATH ${sdl2_SOURCE_DIR})
+
+# Fetch Catch2 for the file format tests
+FetchContent_Declare(
+ Catch2
+ GIT_REPOSITORY https://github.com/catchorg/Catch2.git
+ GIT_TAG v2.13.9 # or a later release
+)
+
+FetchContent_MakeAvailable(Catch2)
+
+# Import some find files
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
+
+project(umbra)
+
+# Common utilities
+add_subdirectory(projs/shadow/shadow-utility)
+
+# Asset management
+add_subdirectory(projs/shadow/shadow-file-format)
+
+# Reflection
+add_subdirectory(projs/shadow/shadow-reflection)
+
+# Core engine
+add_subdirectory(projs/shadow/shadow-engine)
+
+# Runtime executable
+add_subdirectory(projs/shadow/shadow-runtime)
\ No newline at end of file
diff --git a/WORKSPACE b/WORKSPACE
deleted file mode 100644
index 26277c8..0000000
--- a/WORKSPACE
+++ /dev/null
@@ -1,7 +0,0 @@
-workspace(
- name = "umbra",
-)
-
-load("//vendor:deps.bzl", "deps")
-
-deps()
\ No newline at end of file
diff --git a/cmake/FindSDL2.cmake b/cmake/FindSDL2.cmake
new file mode 100644
index 0000000..c563017
--- /dev/null
+++ b/cmake/FindSDL2.cmake
@@ -0,0 +1,388 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# Copyright 2019 Amine Ben Hassouna
+# Copyright 2000-2019 Kitware, Inc. and Contributors
+# All rights reserved.
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+
+# * Neither the name of Kitware, Inc. nor the names of Contributors
+# may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#[=======================================================================[.rst:
+FindSDL2
+--------
+
+Locate SDL2 library
+
+This module defines the following 'IMPORTED' targets:
+
+::
+
+ SDL2::Core
+ The SDL2 library, if found.
+ Libraries should link to SDL2::Core
+
+ SDL2::Main
+ The SDL2main library, if found.
+ Applications should link to SDL2::Main instead of SDL2::Core
+
+
+
+This module will set the following variables in your project:
+
+::
+
+ SDL2_LIBRARIES, the name of the library to link against
+ SDL2_INCLUDE_DIRS, where to find SDL.h
+ SDL2_FOUND, if false, do not try to link to SDL2
+ SDL2MAIN_FOUND, if false, do not try to link to SDL2main
+ SDL2_VERSION_STRING, human-readable string containing the version of SDL2
+
+
+
+This module responds to the following cache variables:
+
+::
+
+ SDL2_PATH
+ Set a custom SDL2 Library path (default: empty)
+
+ SDL2_NO_DEFAULT_PATH
+ Disable search SDL2 Library in default path.
+ If SDL2_PATH (default: ON)
+ Else (default: OFF)
+
+ SDL2_INCLUDE_DIR
+ SDL2 headers path.
+
+ SDL2_LIBRARY
+ SDL2 Library (.dll, .so, .a, etc) path.
+
+ SDL2MAIN_LIBRAY
+ SDL2main Library (.a) path.
+
+ SDL2_BUILDING_LIBRARY
+ This flag is useful only when linking to SDL2_LIBRARIES insead of
+ SDL2::Main. It is required only when building a library that links to
+ SDL2_LIBRARIES, because only applications need main() (No need to also
+ link to SDL2main).
+ If this flag is defined, then no SDL2main will be added to SDL2_LIBRARIES
+ and no SDL2::Main target will be created.
+
+
+Don't forget to include SDLmain.h and SDLmain.m in your project for the
+OS X framework based version. (Other versions link to -lSDL2main which
+this module will try to find on your behalf.) Also for OS X, this
+module will automatically add the -framework Cocoa on your behalf.
+
+
+Additional Note: If you see an empty SDL2_LIBRARY in your project
+configuration, it means CMake did not find your SDL2 library
+(SDL2.dll, libsdl2.so, SDL2.framework, etc). Set SDL2_LIBRARY to point
+to your SDL2 library, and configure again. Similarly, if you see an
+empty SDL2MAIN_LIBRARY, you should set this value as appropriate. These
+values are used to generate the final SDL2_LIBRARIES variable and the
+SDL2::Core and SDL2::Main targets, but when these values are unset,
+SDL2_LIBRARIES, SDL2::Core and SDL2::Main does not get created.
+
+
+$SDL2DIR is an environment variable that would correspond to the
+./configure --prefix=$SDL2DIR used in building SDL2. l.e.galup 9-20-02
+
+
+
+Created by Amine Ben Hassouna:
+ Adapt FindSDL.cmake to SDL2 (FindSDL2.cmake).
+ Add cache variables for more flexibility:
+ SDL2_PATH, SDL2_NO_DEFAULT_PATH (for details, see doc above).
+ Mark 'Threads' as a required dependency for non-OSX systems.
+ Modernize the FindSDL2.cmake module by creating specific targets:
+ SDL2::Core and SDL2::Main (for details, see doc above).
+
+
+Original FindSDL.cmake module:
+ Modified by Eric Wing. Added code to assist with automated building
+ by using environmental variables and providing a more
+ controlled/consistent search behavior. Added new modifications to
+ recognize OS X frameworks and additional Unix paths (FreeBSD, etc).
+ Also corrected the header search path to follow "proper" SDL
+ guidelines. Added a search for SDLmain which is needed by some
+ platforms. Added a search for threads which is needed by some
+ platforms. Added needed compile switches for MinGW.
+
+On OSX, this will prefer the Framework version (if found) over others.
+People will have to manually change the cache value of SDL2_LIBRARY to
+override this selection or set the SDL2_PATH variable or the CMake
+environment CMAKE_INCLUDE_PATH to modify the search paths.
+
+Note that the header path has changed from SDL/SDL.h to just SDL.h
+This needed to change because "proper" SDL convention is #include
+"SDL.h", not . This is done for portability reasons
+because not all systems place things in SDL/ (see FreeBSD).
+#]=======================================================================]
+
+# Define options for searching SDL2 Library in a custom path
+
+set(SDL2_PATH "" CACHE STRING "Custom SDL2 Library path")
+
+set(_SDL2_NO_DEFAULT_PATH OFF)
+if(SDL2_PATH)
+ set(_SDL2_NO_DEFAULT_PATH ON)
+endif()
+
+set(SDL2_NO_DEFAULT_PATH ${_SDL2_NO_DEFAULT_PATH}
+ CACHE BOOL "Disable search SDL2 Library in default path")
+unset(_SDL2_NO_DEFAULT_PATH)
+
+set(SDL2_NO_DEFAULT_PATH_CMD)
+if(SDL2_NO_DEFAULT_PATH)
+ set(SDL2_NO_DEFAULT_PATH_CMD NO_DEFAULT_PATH)
+endif()
+
+# Search for the SDL2 include directory
+find_path(SDL2_INCLUDE_DIR SDL.h
+ HINTS
+ ENV SDL2DIR
+ ${SDL2_NO_DEFAULT_PATH_CMD}
+ PATH_SUFFIXES SDL2
+ # path suffixes to search inside ENV{SDL2DIR}
+ include/SDL2 include
+ PATHS ${SDL2_PATH}
+ DOC "Where the SDL2 headers can be found"
+ )
+
+set(SDL2_INCLUDE_DIRS "${SDL2_INCLUDE_DIR}")
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(VC_LIB_PATH_SUFFIX lib/x64)
+else()
+ set(VC_LIB_PATH_SUFFIX lib/x86)
+endif()
+
+# SDL-2.0 is the name used by FreeBSD ports...
+# don't confuse it for the version number.
+find_library(SDL2_LIBRARY
+ NAMES SDL2 SDL-2.0
+ HINTS
+ ENV SDL2DIR
+ ${SDL2_NO_DEFAULT_PATH_CMD}
+ PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
+ PATHS ${SDL2_PATH}
+ DOC "Where the SDL2 Library can be found"
+ )
+
+set(SDL2_LIBRARIES "${SDL2_LIBRARY}")
+
+if(NOT SDL2_BUILDING_LIBRARY)
+ if(NOT SDL2_INCLUDE_DIR MATCHES ".framework")
+ # Non-OS X framework versions expect you to also dynamically link to
+ # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms
+ # seem to provide SDL2main for compatibility even though they don't
+ # necessarily need it.
+
+ if(SDL2_PATH)
+ set(SDL2MAIN_LIBRARY_PATHS "${SDL2_PATH}")
+ endif()
+
+ if(NOT SDL2_NO_DEFAULT_PATH)
+ set(SDL2MAIN_LIBRARY_PATHS
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+ "${SDL2MAIN_LIBRARY_PATHS}"
+ )
+ endif()
+
+ find_library(SDL2MAIN_LIBRARY
+ NAMES SDL2main
+ HINTS
+ ENV SDL2DIR
+ ${SDL2_NO_DEFAULT_PATH_CMD}
+ PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
+ PATHS ${SDL2MAIN_LIBRARY_PATHS}
+ DOC "Where the SDL2main library can be found"
+ )
+ unset(SDL2MAIN_LIBRARY_PATHS)
+ endif()
+endif()
+
+# SDL2 may require threads on your system.
+# The Apple build may not need an explicit flag because one of the
+# frameworks may already provide it.
+# But for non-OSX systems, I will use the CMake Threads package.
+if(NOT APPLE)
+ find_package(Threads QUIET)
+ if(NOT Threads_FOUND)
+ set(SDL2_THREADS_NOT_FOUND "Could NOT find Threads (Threads is required by SDL2).")
+ if(SDL2_FIND_REQUIRED)
+ message(FATAL_ERROR ${SDL2_THREADS_NOT_FOUND})
+ else()
+ if(NOT SDL2_FIND_QUIETLY)
+ message(STATUS ${SDL2_THREADS_NOT_FOUND})
+ endif()
+ return()
+ endif()
+ unset(SDL2_THREADS_NOT_FOUND)
+ endif()
+endif()
+
+# MinGW needs an additional link flag, -mwindows
+# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -mwindows
+if(MINGW)
+ set(MINGW32_LIBRARY mingw32 "-mwindows" CACHE STRING "link flags for MinGW")
+endif()
+
+if(SDL2_LIBRARY)
+ # For SDL2main
+ if(SDL2MAIN_LIBRARY AND NOT SDL2_BUILDING_LIBRARY)
+ list(FIND SDL2_LIBRARIES "${SDL2MAIN_LIBRARY}" _SDL2_MAIN_INDEX)
+ if(_SDL2_MAIN_INDEX EQUAL -1)
+ set(SDL2_LIBRARIES "${SDL2MAIN_LIBRARY}" ${SDL2_LIBRARIES})
+ endif()
+ unset(_SDL2_MAIN_INDEX)
+ endif()
+
+ # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa.
+ # CMake doesn't display the -framework Cocoa string in the UI even
+ # though it actually is there if I modify a pre-used variable.
+ # I think it has something to do with the CACHE STRING.
+ # So I use a temporary variable until the end so I can set the
+ # "real" variable in one-shot.
+ if(APPLE)
+ set(SDL2_LIBRARIES ${SDL2_LIBRARIES} -framework Cocoa)
+ endif()
+
+ # For threads, as mentioned Apple doesn't need this.
+ # In fact, there seems to be a problem if I used the Threads package
+ # and try using this line, so I'm just skipping it entirely for OS X.
+ if(NOT APPLE)
+ set(SDL2_LIBRARIES ${SDL2_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+ endif()
+
+ # For MinGW library
+ if(MINGW)
+ set(SDL2_LIBRARIES ${MINGW32_LIBRARY} ${SDL2_LIBRARIES})
+ endif()
+
+endif()
+
+# Read SDL2 version
+if(SDL2_INCLUDE_DIR AND EXISTS "${SDL2_INCLUDE_DIR}/SDL_version.h")
+ file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+[0-9]+$")
+ file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MINOR_VERSION[ \t]+[0-9]+$")
+ file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_PATCHLEVEL[ \t]+[0-9]+$")
+ string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MAJOR "${SDL2_VERSION_MAJOR_LINE}")
+ string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MINOR "${SDL2_VERSION_MINOR_LINE}")
+ string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_PATCH "${SDL2_VERSION_PATCH_LINE}")
+ set(SDL2_VERSION_STRING ${SDL2_VERSION_MAJOR}.${SDL2_VERSION_MINOR}.${SDL2_VERSION_PATCH})
+ unset(SDL2_VERSION_MAJOR_LINE)
+ unset(SDL2_VERSION_MINOR_LINE)
+ unset(SDL2_VERSION_PATCH_LINE)
+ unset(SDL2_VERSION_MAJOR)
+ unset(SDL2_VERSION_MINOR)
+ unset(SDL2_VERSION_PATCH)
+endif()
+
+include(FindPackageHandleStandardArgs)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2
+ REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR
+ VERSION_VAR SDL2_VERSION_STRING)
+
+if(SDL2MAIN_LIBRARY)
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2main
+ REQUIRED_VARS SDL2MAIN_LIBRARY SDL2_INCLUDE_DIR
+ VERSION_VAR SDL2_VERSION_STRING)
+endif()
+
+
+mark_as_advanced(SDL2_PATH
+ SDL2_NO_DEFAULT_PATH
+ SDL2_LIBRARY
+ SDL2MAIN_LIBRARY
+ SDL2_INCLUDE_DIR
+ SDL2_BUILDING_LIBRARY)
+
+
+# SDL2:: targets (SDL2::Core and SDL2::Main)
+if(SDL2_FOUND)
+
+ # SDL2::Core target
+ if(SDL2_LIBRARY AND NOT TARGET SDL2::Core)
+ add_library(SDL2::Core UNKNOWN IMPORTED)
+ set_target_properties(SDL2::Core PROPERTIES
+ IMPORTED_LOCATION "${SDL2_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}")
+
+ if(APPLE)
+ # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa.
+ # For more details, please see above.
+ set_property(TARGET SDL2::Core APPEND PROPERTY
+ INTERFACE_LINK_OPTIONS -framework Cocoa)
+ else()
+ # For threads, as mentioned Apple doesn't need this.
+ # For more details, please see above.
+ set_property(TARGET SDL2::Core APPEND PROPERTY
+ INTERFACE_LINK_LIBRARIES Threads::Threads)
+ endif()
+ endif()
+
+ # SDL2::Main target
+ # Applications should link to SDL2::Main instead of SDL2::Core
+ # For more details, please see above.
+ if(NOT SDL2_BUILDING_LIBRARY AND NOT TARGET SDL2::Main)
+
+ if(SDL2_INCLUDE_DIR MATCHES ".framework" OR NOT SDL2MAIN_LIBRARY)
+ add_library(SDL2::Main INTERFACE IMPORTED)
+ set_property(TARGET SDL2::Main PROPERTY
+ INTERFACE_LINK_LIBRARIES SDL2::Core)
+ elseif(SDL2MAIN_LIBRARY)
+ # MinGW requires that the mingw32 library is specified before the
+ # libSDL2main.a static library when linking.
+ # The SDL2::MainInternal target is used internally to make sure that
+ # CMake respects this condition.
+ add_library(SDL2::MainInternal UNKNOWN IMPORTED)
+ set_property(TARGET SDL2::MainInternal PROPERTY
+ IMPORTED_LOCATION "${SDL2MAIN_LIBRARY}")
+ set_property(TARGET SDL2::MainInternal PROPERTY
+ INTERFACE_LINK_LIBRARIES SDL2::Core)
+
+ add_library(SDL2::Main INTERFACE IMPORTED)
+
+ if(MINGW)
+ # MinGW needs an additional link flag '-mwindows' and link to mingw32
+ set_property(TARGET SDL2::Main PROPERTY
+ INTERFACE_LINK_LIBRARIES "mingw32" "-mwindows")
+ endif()
+
+ set_property(TARGET SDL2::Main APPEND PROPERTY
+ INTERFACE_LINK_LIBRARIES SDL2::MainInternal)
+ endif()
+
+ endif()
+endif()
diff --git a/projs/shadow-engine/BUILD.bazel b/projs/shadow-engine/BUILD.bazel
deleted file mode 100644
index 10916b9..0000000
--- a/projs/shadow-engine/BUILD.bazel
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-cc_library(
- name = "shadow-engine",
- srcs = glob(["src/**/*.cpp", "src/**/*.h"]),
- hdrs = glob(["src/**/*.h"]),
- strip_include_prefix = "src/",
- includes = [],
- copts = [
- "/std:c++20"
- ],
- deps = [
- "//projs/shadow-utility",
- "@sdl2"
- ],
- visibility = ["//visibility:public"],
-)
\ No newline at end of file
diff --git a/projs/shadow-engine/shadow-engine.cpp b/projs/shadow-engine/shadow-engine.cpp
deleted file mode 100644
index 0ffdd3f..0000000
--- a/projs/shadow-engine/shadow-engine.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-#include
-#include
-#include
-
-// You must include the command line parameters for your main function to be recognized by SDL
-int main(int argc, char** args) {
-
- // Pointers to our window and surface
- SDL_Surface* winSurface = NULL;
- SDL_Window* window = NULL;
-
-
-
- // Initialize SDL. SDL_Init will return -1 if it fails.
- if ( SDL_Init( SDL_INIT_EVERYTHING ) < 0 ) {
- std::cout << "Error initializing SDL: " << SDL_GetError() << std::endl;
- system("pause");
- // End the program
- return 1;
- }
-
- // Create our window
- window = SDL_CreateWindow( "Example", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_SHOWN );
-
- // Make sure creating the window succeeded
- if ( !window ) {
- std::cout << "Error creating window: " << SDL_GetError() << std::endl;
- system("pause");
- // End the program
- return 1;
- }
-
- // Get the surface from the window
- winSurface = SDL_GetWindowSurface( window );
-
- // Make sure getting the surface succeeded
- if ( !winSurface ) {
- std::cout << "Error getting surface: " << SDL_GetError() << std::endl;
- system("pause");
- // End the program
- return 1;
- }
-
- // Fill the window with a white rectangle
- SDL_FillRect( winSurface, NULL, SDL_MapRGB( winSurface->format, 255, 255, 255 ) );
-
- // Update the window display
- SDL_UpdateWindowSurface( window );
-
- // Wait
- system("pause");
-
- // Destroy the window. This will also destroy the surface
- SDL_DestroyWindow( window );
-
- // Quit SDL
- SDL_Quit();
-
- // End the program
- return 0;
-}
\ No newline at end of file
diff --git a/projs/shadow-file-format/BUILD b/projs/shadow-file-format/BUILD
deleted file mode 100644
index 2ffe3ac..0000000
--- a/projs/shadow-file-format/BUILD
+++ /dev/null
@@ -1,31 +0,0 @@
-load("@rules_cc//cc:defs.bzl", "cc_library")
-load("@rules_cc//cc:defs.bzl", "cc_binary")
-
-cc_library(
- name = "shadow-file-format",
- srcs = glob(["src/**/*.cpp", "src/**/*.h"]),
- hdrs = glob(["src/**/*.h"]),
- strip_include_prefix = "src/",
- includes = [],
- copts = [
- "/std:c++17"
- ],
- deps = [
- "//projs/shadow-utility"
- ],
- visibility = ["//visibility:public"],
-)
-
-cc_test(
- name = "test",
- srcs = glob(["test/**/*.cpp", "test/**/*.h"]),
- includes = [],
- defines = [ "CATCH_CONFIG_MAIN" ],
- copts = [
- "/std:c++17"
- ],
- deps = [
- "//projs/shadow-file-format",
- "@catch2"
- ],
-)
\ No newline at end of file
diff --git a/projs/shadow-runtime/BUILD.bazel b/projs/shadow-runtime/BUILD.bazel
deleted file mode 100644
index 4915d0d..0000000
--- a/projs/shadow-runtime/BUILD.bazel
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-cc_binary(
- name = "shadow-runtime",
- srcs = glob(["src/**/*.cpp", "src/**/*.h"]),
- includes = [],
- copts = [
- "/std:c++20"
- ],
- deps = [
- "//projs/shadow-engine",
- "@sdl2"
- ],
-)
\ No newline at end of file
diff --git a/projs/shadow-runtime/src/main.h b/projs/shadow-runtime/src/main.h
deleted file mode 100644
index 6d17370..0000000
--- a/projs/shadow-runtime/src/main.h
+++ /dev/null
@@ -1,8 +0,0 @@
-//
-// Created by dpete on 2022-06-20.
-//
-
-#ifndef UMBRA_MAIN_H
-#define UMBRA_MAIN_H
-
-#endif //UMBRA_MAIN_H
diff --git a/projs/shadow-utility/BUILD b/projs/shadow-utility/BUILD
deleted file mode 100644
index e051055..0000000
--- a/projs/shadow-utility/BUILD
+++ /dev/null
@@ -1,15 +0,0 @@
-load("@rules_cc//cc:defs.bzl", "cc_library")
-
-cc_library(
- name = "shadow-utility",
- srcs = glob(["**/*.cpp", "**/*.h"]),
- hdrs = glob(["**/*.h"]),
- strip_include_prefix = "src/",
- includes = [],
- copts = [
- "/std:c++20"
- ],
- deps = [
- ],
- visibility = ["//visibility:public"],
-)
\ No newline at end of file
diff --git a/projs/shadow/shadow-engine/CMakeLists.txt b/projs/shadow/shadow-engine/CMakeLists.txt
new file mode 100644
index 0000000..f14be03
--- /dev/null
+++ b/projs/shadow/shadow-engine/CMakeLists.txt
@@ -0,0 +1,12 @@
+find_package(Vulkan REQUIRED)
+find_package(SDL2 REQUIRED)
+
+set(CMAKE_CXX_STANDARD 20)
+
+FILE(GLOB_RECURSE SOURCES src/*.cpp)
+FILE(GLOB_RECURSE HEADERS src/*.h)
+
+add_library(shadow-engine ${SOURCES})
+
+target_include_directories(shadow-engine PRIVATE ${SDL2_INCLUDE_DIRS} PUBLIC ${HEADERS})
+target_link_libraries(shadow-engine PRIVATE Vulkan::Vulkan PUBLIC SDL2::Core shadow-reflect shadow-asset)
\ No newline at end of file
diff --git a/projs/shadow/shadow-engine/src/core/Module.cpp b/projs/shadow/shadow-engine/src/core/Module.cpp
new file mode 100644
index 0000000..418f01c
--- /dev/null
+++ b/projs/shadow/shadow-engine/src/core/Module.cpp
@@ -0,0 +1,8 @@
+//
+// Created by dpete on 2022-07-06.
+//
+
+#include "Module.h"
+
+namespace ShadowEngine {
+} // ShadowEngine
\ No newline at end of file
diff --git a/projs/shadow/shadow-engine/src/core/Module.h b/projs/shadow/shadow-engine/src/core/Module.h
new file mode 100644
index 0000000..a26e465
--- /dev/null
+++ b/projs/shadow/shadow-engine/src/core/Module.h
@@ -0,0 +1,52 @@
+#ifndef UMBRA_MODULE_H
+#define UMBRA_MODULE_H
+
+#include "../../../shadow-reflection/src/SHObject.h"
+
+namespace ShadowEngine {
+
+ ///
+ /// ShadowModules are the base of the engine. They add core abilities.
+ ///
+ class Module : public SHObject
+ {
+ SHObject_Base(Module)
+
+ public:
+
+ ///
+ /// Pre Init is called when the module is added to the engine
+ ///
+ virtual void PreInit() = 0;
+
+
+ ///
+ /// Init is called after all the modules are added
+ ///
+ virtual void Init() = 0;
+
+ ///
+ /// update is called each frame
+ ///
+ virtual void Update() = 0;
+
+ virtual void Render() = 0;
+
+ virtual void LateRender() = 0;
+
+ virtual void AfterFrameEnd() {};
+
+ ///
+ /// Returns the name of the module
+ ///
+ ///
+ virtual std::string GetName() = 0;
+
+
+ Module();
+ virtual ~Module();
+ };
+
+} // ShadowEngine
+
+#endif //UMBRA_MODULE_H
diff --git a/projs/shadow/shadow-engine/src/core/ModuleManager.cpp b/projs/shadow/shadow-engine/src/core/ModuleManager.cpp
new file mode 100644
index 0000000..57f931c
--- /dev/null
+++ b/projs/shadow/shadow-engine/src/core/ModuleManager.cpp
@@ -0,0 +1,5 @@
+//
+// Created by dpete on 2022-07-06.
+//
+
+#include "ModuleManager.h"
diff --git a/projs/shadow/shadow-engine/src/core/ModuleManager.h b/projs/shadow/shadow-engine/src/core/ModuleManager.h
new file mode 100644
index 0000000..1ba1e8f
--- /dev/null
+++ b/projs/shadow/shadow-engine/src/core/ModuleManager.h
@@ -0,0 +1,51 @@
+#ifndef UMBRA_MODULEMANAGER_H
+#define UMBRA_MODULEMANAGER_H
+
+#include
+#include
+#include "Module.h"
+
+namespace ShadowEngine {
+
+ class ModuleRef{
+ std::unique_ptr module;
+ std::string domain;
+ };
+
+ class ModuleManager {
+ public:
+ static ModuleManager *instance;
+
+ std::list modules;
+
+ ModuleManager();
+
+ ~ModuleManager();
+
+ void PushModule(Module *module);
+
+ Module &GetModule(std::string name);
+
+ template
+ T *GetModuleByType() {
+ for (auto &module: modules) {
+ if (module->GetTypeId() == T::TypeId())
+ return dynamic_cast(module.get());
+ }
+ //SH_CORE_ERROR("Can't find the module {0}", T::Type());
+ return nullptr;
+ }
+
+ void Init();
+
+ void Update();
+
+ void LateRender();
+
+ void Render();
+
+ void AfterFrameEnd();
+ };
+}
+
+#endif //UMBRA_MODULEMANAGER_H
diff --git a/projs/shadow-engine/src/core/ShadowApplication.cpp b/projs/shadow/shadow-engine/src/core/ShadowApplication.cpp
similarity index 82%
rename from projs/shadow-engine/src/core/ShadowApplication.cpp
rename to projs/shadow/shadow-engine/src/core/ShadowApplication.cpp
index 1b3fb8e..39a1385 100644
--- a/projs/shadow-engine/src/core/ShadowApplication.cpp
+++ b/projs/shadow/shadow-engine/src/core/ShadowApplication.cpp
@@ -2,8 +2,6 @@
#include "Time.h"
-#include
-
namespace ShadowEngine {
ShadowApplication* ShadowApplication::instance = nullptr;
@@ -21,10 +19,13 @@ namespace ShadowEngine {
{
this->no_gui = true;
}
+ if(param == "-game")
+ {
+ this->game = argv[i+1];
+ }
}
}
-
-
+
//game = _setupFunc();
}
@@ -69,8 +70,14 @@ namespace ShadowEngine {
void ShadowApplication::Start()
{
+ SDL_Event event;
while (running)
{
+ while (SDL_PollEvent(&event)) { // poll until all events are handled!
+ if (event.type == SDL_QUIT)
+ running = false;
+ }
+
Time::UpdateTime();
}
}
diff --git a/projs/shadow-engine/src/core/ShadowApplication.h b/projs/shadow/shadow-engine/src/core/ShadowApplication.h
similarity index 96%
rename from projs/shadow-engine/src/core/ShadowApplication.h
rename to projs/shadow/shadow-engine/src/core/ShadowApplication.h
index 6688f51..6bf578c 100644
--- a/projs/shadow-engine/src/core/ShadowApplication.h
+++ b/projs/shadow/shadow-engine/src/core/ShadowApplication.h
@@ -1,6 +1,8 @@
#pragma once
#include "ShadowWindow.h"
+#include
+
namespace ShadowEngine {
///
@@ -30,6 +32,8 @@ namespace ShadowEngine {
bool running = true;
bool no_gui = false;
+
+ std::string game = "";
public:
///
diff --git a/projs/shadow-engine/src/core/ShadowWindow.cpp b/projs/shadow/shadow-engine/src/core/ShadowWindow.cpp
similarity index 100%
rename from projs/shadow-engine/src/core/ShadowWindow.cpp
rename to projs/shadow/shadow-engine/src/core/ShadowWindow.cpp
diff --git a/projs/shadow-engine/src/core/ShadowWindow.h b/projs/shadow/shadow-engine/src/core/ShadowWindow.h
similarity index 92%
rename from projs/shadow-engine/src/core/ShadowWindow.h
rename to projs/shadow/shadow-engine/src/core/ShadowWindow.h
index f74d935..68d71c4 100644
--- a/projs/shadow-engine/src/core/ShadowWindow.h
+++ b/projs/shadow/shadow-engine/src/core/ShadowWindow.h
@@ -1,6 +1,6 @@
#pragma once
-#include
+#include
class ShadowWindow
{
diff --git a/projs/shadow-engine/src/core/Time.cpp b/projs/shadow/shadow-engine/src/core/Time.cpp
similarity index 100%
rename from projs/shadow-engine/src/core/Time.cpp
rename to projs/shadow/shadow-engine/src/core/Time.cpp
diff --git a/projs/shadow-engine/src/core/Time.h b/projs/shadow/shadow-engine/src/core/Time.h
similarity index 100%
rename from projs/shadow-engine/src/core/Time.h
rename to projs/shadow/shadow-engine/src/core/Time.h
diff --git a/projs/shadow-entity/shadow-entity.cpp b/projs/shadow/shadow-entity/shadow-entity.cpp
similarity index 100%
rename from projs/shadow-entity/shadow-entity.cpp
rename to projs/shadow/shadow-entity/shadow-entity.cpp
diff --git a/projs/shadow/shadow-file-format/CMakeLists.txt b/projs/shadow/shadow-file-format/CMakeLists.txt
new file mode 100644
index 0000000..e9a94b4
--- /dev/null
+++ b/projs/shadow/shadow-file-format/CMakeLists.txt
@@ -0,0 +1,20 @@
+set(CMAKE_CXX_STANDARD 20)
+
+# Set up Catch2 testing
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
+enable_testing()
+
+# Set up asset sourceset
+FILE(GLOB_RECURSE SOURCES src/*.cpp src/*.h)
+FILE(GLOB_RECURSE TESTS test/*.cpp)
+
+add_library(shadow-asset ${SOURCES})
+
+# Set up test executable
+add_executable(shadow-asset-test ${TESTS})
+target_link_libraries(shadow-asset-test PRIVATE Catch2::Catch2 shadow-utils)
+
+# Enable testing on the executable
+include(CTest)
+include(Catch)
+catch_discover_tests(shadow-asset-test)
\ No newline at end of file
diff --git a/projs/shadow-file-format/SFFElement.natvis b/projs/shadow/shadow-file-format/SFFElement.natvis
similarity index 100%
rename from projs/shadow-file-format/SFFElement.natvis
rename to projs/shadow/shadow-file-format/SFFElement.natvis
diff --git a/projs/shadow/shadow-file-format/cmake/Catch.cmake b/projs/shadow/shadow-file-format/cmake/Catch.cmake
new file mode 100644
index 0000000..c96c578
--- /dev/null
+++ b/projs/shadow/shadow-file-format/cmake/Catch.cmake
@@ -0,0 +1,90 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#-----------------------------------------------------------------------------
+
+function(catch_discover_tests TARGET)
+ cmake_parse_arguments(
+ ""
+ ""
+ "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;REPORTER;OUTPUT_DIR;OUTPUT_PREFIX;OUTPUT_SUFFIX"
+ "TEST_SPEC;EXTRA_ARGS;PROPERTIES"
+ ${ARGN}
+ )
+
+ if(NOT _WORKING_DIRECTORY)
+ set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+ endif()
+ if(NOT _TEST_LIST)
+ set(_TEST_LIST ${TARGET}_TESTS)
+ endif()
+
+ ## Generate a unique name based on the extra arguments
+ string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS} ${_REPORTER} ${_OUTPUT_DIR} ${_OUTPUT_PREFIX} ${_OUTPUT_SUFFIX}")
+ string(SUBSTRING ${args_hash} 0 7 args_hash)
+
+ # Define rule to generate test list for aforementioned test executable
+ set(ctest_include_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake")
+ set(ctest_tests_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake")
+ get_property(crosscompiling_emulator
+ TARGET ${TARGET}
+ PROPERTY CROSSCOMPILING_EMULATOR
+ )
+ add_custom_command(
+ TARGET ${TARGET} POST_BUILD
+ BYPRODUCTS "${ctest_tests_file}"
+ COMMAND "${CMAKE_COMMAND}"
+ -D "TEST_TARGET=${TARGET}"
+ -D "TEST_EXECUTABLE=$"
+ -D "TEST_EXECUTOR=${crosscompiling_emulator}"
+ -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}"
+ -D "TEST_SPEC=${_TEST_SPEC}"
+ -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}"
+ -D "TEST_PROPERTIES=${_PROPERTIES}"
+ -D "TEST_PREFIX=${_TEST_PREFIX}"
+ -D "TEST_SUFFIX=${_TEST_SUFFIX}"
+ -D "TEST_LIST=${_TEST_LIST}"
+ -D "TEST_REPORTER=${_REPORTER}"
+ -D "TEST_OUTPUT_DIR=${_OUTPUT_DIR}"
+ -D "TEST_OUTPUT_PREFIX=${_OUTPUT_PREFIX}"
+ -D "TEST_OUTPUT_SUFFIX=${_OUTPUT_SUFFIX}"
+ -D "CTEST_FILE=${ctest_tests_file}"
+ -P "${_CATCH_DISCOVER_TESTS_SCRIPT}"
+ VERBATIM
+ )
+
+ file(WRITE "${ctest_include_file}"
+ "if(EXISTS \"${ctest_tests_file}\")\n"
+ " include(\"${ctest_tests_file}\")\n"
+ "else()\n"
+ " add_test(${TARGET}_NOT_BUILT-${args_hash} ${TARGET}_NOT_BUILT-${args_hash})\n"
+ "endif()\n"
+ )
+
+ if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0")
+ # Add discovered tests to directory TEST_INCLUDE_FILES
+ set_property(DIRECTORY
+ APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
+ )
+ else()
+ # Add discovered tests as directory TEST_INCLUDE_FILE if possible
+ get_property(test_include_file_set DIRECTORY PROPERTY TEST_INCLUDE_FILE SET)
+ if (NOT ${test_include_file_set})
+ set_property(DIRECTORY
+ PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}"
+ )
+ else()
+ message(FATAL_ERROR
+ "Cannot set more than one TEST_INCLUDE_FILE"
+ )
+ endif()
+ endif()
+
+endfunction()
+
+###############################################################################
+
+set(_CATCH_DISCOVER_TESTS_SCRIPT
+ ${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake
+ CACHE INTERNAL "Catch2 full path to CatchAddTests.cmake helper file"
+ )
\ No newline at end of file
diff --git a/projs/shadow/shadow-file-format/cmake/CatchAddTests.cmake b/projs/shadow/shadow-file-format/cmake/CatchAddTests.cmake
new file mode 100644
index 0000000..6ba6a04
--- /dev/null
+++ b/projs/shadow/shadow-file-format/cmake/CatchAddTests.cmake
@@ -0,0 +1,135 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+set(prefix "${TEST_PREFIX}")
+set(suffix "${TEST_SUFFIX}")
+set(spec ${TEST_SPEC})
+set(extra_args ${TEST_EXTRA_ARGS})
+set(properties ${TEST_PROPERTIES})
+set(reporter ${TEST_REPORTER})
+set(output_dir ${TEST_OUTPUT_DIR})
+set(output_prefix ${TEST_OUTPUT_PREFIX})
+set(output_suffix ${TEST_OUTPUT_SUFFIX})
+set(script)
+set(suite)
+set(tests)
+
+function(add_command NAME)
+ set(_args "")
+ # use ARGV* instead of ARGN, because ARGN splits arrays into multiple arguments
+ math(EXPR _last_arg ${ARGC}-1)
+ foreach(_n RANGE 1 ${_last_arg})
+ set(_arg "${ARGV${_n}}")
+ if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
+ set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument
+ else()
+ set(_args "${_args} ${_arg}")
+ endif()
+ endforeach()
+ set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE)
+endfunction()
+
+# Run test executable to get list of available tests
+if(NOT EXISTS "${TEST_EXECUTABLE}")
+ message(FATAL_ERROR
+ "Specified test executable '${TEST_EXECUTABLE}' does not exist"
+ )
+endif()
+execute_process(
+ COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only
+ OUTPUT_VARIABLE output
+ RESULT_VARIABLE result
+ WORKING_DIRECTORY "${TEST_WORKING_DIR}"
+)
+# Catch --list-test-names-only reports the number of tests, so 0 is... surprising
+if(${result} EQUAL 0)
+ message(WARNING
+ "Test executable '${TEST_EXECUTABLE}' contains no tests!\n"
+ )
+elseif(${result} LESS 0)
+ message(FATAL_ERROR
+ "Error running test executable '${TEST_EXECUTABLE}':\n"
+ " Result: ${result}\n"
+ " Output: ${output}\n"
+ )
+endif()
+
+string(REPLACE "\n" ";" output "${output}")
+
+# Run test executable to get list of available reporters
+execute_process(
+ COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-reporters
+ OUTPUT_VARIABLE reporters_output
+ RESULT_VARIABLE reporters_result
+ WORKING_DIRECTORY "${TEST_WORKING_DIR}"
+)
+if(${reporters_result} EQUAL 0)
+ message(WARNING
+ "Test executable '${TEST_EXECUTABLE}' contains no reporters!\n"
+ )
+elseif(${reporters_result} LESS 0)
+ message(FATAL_ERROR
+ "Error running test executable '${TEST_EXECUTABLE}':\n"
+ " Result: ${reporters_result}\n"
+ " Output: ${reporters_output}\n"
+ )
+endif()
+string(FIND "${reporters_output}" "${reporter}" reporter_is_valid)
+if(reporter AND ${reporter_is_valid} EQUAL -1)
+ message(FATAL_ERROR
+ "\"${reporter}\" is not a valid reporter!\n"
+ )
+endif()
+
+# Prepare reporter
+if(reporter)
+ set(reporter_arg "--reporter ${reporter}")
+endif()
+
+# Prepare output dir
+if(output_dir AND NOT IS_ABSOLUTE ${output_dir})
+ set(output_dir "${TEST_WORKING_DIR}/${output_dir}")
+ if(NOT EXISTS ${output_dir})
+ file(MAKE_DIRECTORY ${output_dir})
+ endif()
+endif()
+
+# Parse output
+foreach(line ${output})
+ set(../test ${line})
+ # Escape characters in test case names that would be parsed by Catch2
+ set(test_name ${test})
+ #foreach(char , [ ])
+ #string(REPLACE ${char} "\\${char}" test_name ${test_name})
+ #endforeach(char)
+ # ...add output dir
+ if(output_dir)
+ string(REGEX REPLACE "[^A-Za-z0-9_]" "_" test_name_clean ${test_name})
+ set(output_dir_arg "--out ${output_dir}/${output_prefix}${test_name_clean}${output_suffix}")
+ endif()
+
+ # ...and add to script
+ add_command(add_test
+ "${prefix}${test}${suffix}"
+ ${TEST_EXECUTOR}
+ "${TEST_EXECUTABLE}"
+ "${test_name}"
+ ${extra_args}
+ "${reporter_arg}"
+ "${output_dir_arg}"
+ )
+ add_command(set_tests_properties
+ "${prefix}${test}${suffix}"
+ PROPERTIES
+ WORKING_DIRECTORY "${TEST_WORKING_DIR}"
+ ${properties}
+ )
+ list(APPEND tests "${prefix}${test}${suffix}")
+endforeach()
+
+# Create a list of all discovered tests, which users may use to e.g. set
+# properties on the tests
+add_command(set ${TEST_LIST} ${tests})
+
+# Write CTest script
+file(WRITE "${CTEST_FILE}" "${script}")
\ No newline at end of file
diff --git a/projs/shadow-file-format/src/SFFElement.cpp b/projs/shadow/shadow-file-format/src/SFFElement.cpp
similarity index 100%
rename from projs/shadow-file-format/src/SFFElement.cpp
rename to projs/shadow/shadow-file-format/src/SFFElement.cpp
diff --git a/projs/shadow-file-format/src/SFFElement.h b/projs/shadow/shadow-file-format/src/SFFElement.h
similarity index 100%
rename from projs/shadow-file-format/src/SFFElement.h
rename to projs/shadow/shadow-file-format/src/SFFElement.h
diff --git a/projs/shadow-file-format/src/SFFParser.cpp b/projs/shadow/shadow-file-format/src/SFFParser.cpp
similarity index 97%
rename from projs/shadow-file-format/src/SFFParser.cpp
rename to projs/shadow/shadow-file-format/src/SFFParser.cpp
index 4056721..ba5a3fe 100644
--- a/projs/shadow-file-format/src/SFFParser.cpp
+++ b/projs/shadow/shadow-file-format/src/SFFParser.cpp
@@ -1,9 +1,8 @@
#include "SFFParser.h"
+#include "../../shadow-utility/src/string-helpers.h"
#include
-#include "string-helpers.h"
-
namespace Shadow::SFF {
SFFElement* SFFParser::ReadFromStream(std::istream& stream)
diff --git a/projs/shadow-file-format/src/SFFParser.h b/projs/shadow/shadow-file-format/src/SFFParser.h
similarity index 100%
rename from projs/shadow-file-format/src/SFFParser.h
rename to projs/shadow/shadow-file-format/src/SFFParser.h
diff --git a/projs/shadow-file-format/src/SFFVersion.h b/projs/shadow/shadow-file-format/src/SFFVersion.h
similarity index 100%
rename from projs/shadow-file-format/src/SFFVersion.h
rename to projs/shadow/shadow-file-format/src/SFFVersion.h
diff --git a/projs/shadow-file-format/src/SFFWriter.cpp b/projs/shadow/shadow-file-format/src/SFFWriter.cpp
similarity index 100%
rename from projs/shadow-file-format/src/SFFWriter.cpp
rename to projs/shadow/shadow-file-format/src/SFFWriter.cpp
diff --git a/projs/shadow-file-format/src/SFFWriter.h b/projs/shadow/shadow-file-format/src/SFFWriter.h
similarity index 100%
rename from projs/shadow-file-format/src/SFFWriter.h
rename to projs/shadow/shadow-file-format/src/SFFWriter.h
diff --git a/projs/shadow-file-format/src/Shadow.FileFormat.ixx b/projs/shadow/shadow-file-format/src/Shadow.FileFormat.ixx
similarity index 100%
rename from projs/shadow-file-format/src/Shadow.FileFormat.ixx
rename to projs/shadow/shadow-file-format/src/Shadow.FileFormat.ixx
diff --git a/projs/shadow-file-format/test/Catch2Test.cpp b/projs/shadow/shadow-file-format/test/Catch2Test.cpp
similarity index 78%
rename from projs/shadow-file-format/test/Catch2Test.cpp
rename to projs/shadow/shadow-file-format/test/Catch2Test.cpp
index 07ed832..6592347 100644
--- a/projs/shadow-file-format/test/Catch2Test.cpp
+++ b/projs/shadow/shadow-file-format/test/Catch2Test.cpp
@@ -1,3 +1,4 @@
+#define CATCH_CONFIG_MAIN
#include
TEST_CASE("15 is less than 20", "[numbers]") {
diff --git a/projs/shadow/shadow-file-format/test/catch2/catch.hpp b/projs/shadow/shadow-file-format/test/catch2/catch.hpp
new file mode 100644
index 0000000..d2a1242
--- /dev/null
+++ b/projs/shadow/shadow-file-format/test/catch2/catch.hpp
@@ -0,0 +1,17970 @@
+/*
+ * Catch v2.13.9
+ * Generated: 2022-04-12 22:37:23.260201
+ * ----------------------------------------------------------
+ * This file has been merged from multiple headers. Please don't edit it directly
+ * Copyright (c) 2022 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 9
+
+#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
+
+// See e.g.:
+// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
+#ifdef __APPLE__
+# include
+# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \
+ (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)
+# define CATCH_PLATFORM_MAC
+# elif (defined(TARGET_OS_IPHONE) && 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
+
+// Only GCC compiler should be used in this block, so other compilers trying to
+// mask themselves as GCC should be ignored.
+#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__)
+# 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)
+
+// 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
+
+# if !defined(__clang__) // Handle Clang masquerading for msvc
+
+// 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 // MSVC_TRADITIONAL
+
+// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop`
+# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
+# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
+# 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 defined(__cpp_lib_byte) && (__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 class Final, template< typename...> class...Containers, typename...Types>\
+ struct create, TypeList> { using type = typename append, typename rewrap, Types...>::type...>::type; };\
+ template class Final, template class List, typename...Ts>\
+ struct convert> { using type = typename append,TypeList...>::type; };
+
+#define INTERNAL_CATCH_NTTP_1(signature, ...)\
+ template struct Nttp{};\
+ template\
+ constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
+ template class...> struct NttpTemplateTypeList{};\
+ template class...Cs>\
+ constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList { return {}; } \
+ \
+ template< template class Container, template class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+ struct rewrap, List<__VA_ARGS__>> { using type = TypeList>; };\
+ template< template class Container, template class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
+ struct rewrap, List<__VA_ARGS__>, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\
+ template class Final, template class...Containers, typename...Types>\
+ struct create, TypeList> { using type = typename append, typename rewrap, Types...>::type...>::type; };
+
+#define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
+ template\
+ static void TestName()
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
+ template\
+ static void TestName()
+
+#define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
+ template\
+ static void TestName()
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
+ template\
+ static void TestName()
+
+#define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
+ template\
+ void reg_test(TypeList, Catch::NameAndTags nameAndTags)\
+ {\
+ Catch::AutoReg( Catch::makeTestInvoker(&TestFunc), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
+ }
+
+#define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
+ template\
+ void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
+ {\
+ Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
+ }
+
+#define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
+ template\
+ void reg_test(TypeList, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
+ {\
+ Catch::AutoReg( Catch::makeTestInvoker(&TestName::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
+ }
+
+#define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
+ template\
+ void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
+ {\
+ Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
+ }
+
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
+ template \
+ struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
+ void test();\
+ }
+
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
+ template \
+ struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
+ void test();\
+ }
+
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
+ template \
+ void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName::test()
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
+ template \
+ void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+#define INTERNAL_CATCH_NTTP_0
+#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__),INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_0)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)
+#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)
+#else
+#define INTERNAL_CATCH_NTTP_0(signature)
+#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)( __VA_ARGS__))
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))
+#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))
+#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))
+#endif
+
+// end catch_preprocessor.hpp
+// start catch_meta.hpp
+
+
+#include
+
+namespace Catch {
+ template
+ struct always_false : std::false_type {};
+
+ template struct true_given : std::true_type {};
+ struct is_callable_tester {
+ template
+ true_given()(std::declval()...))> static test(int);
+ template
+ std::false_type static test(...);
+ };
+
+ template
+ struct is_callable;
+
+ template
+ struct is_callable : decltype(is_callable_tester::test(0)) {};
+
+#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
+ // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
+ // replaced with std::invoke_result here.
+ template
+ using FunctionReturnType = std::remove_reference_t>>;
+#else
+ // Keep ::type here because we still support C++11
+ template
+ using FunctionReturnType = typename std::remove_reference::type>::type>::type;
+#endif
+
+} // namespace Catch
+
+namespace mpl_{
+ struct na;
+}
+
+// end catch_meta.hpp
+namespace Catch {
+
+template
+class TestInvokerAsMethod : public ITestInvoker {
+ void (C::*m_testAsMethod)();
+public:
+ TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
+
+ void invoke() const override {
+ C obj;
+ (obj.*m_testAsMethod)();
+ }
+};
+
+auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
+
+template
+auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
+ return new(std::nothrow) TestInvokerAsMethod( testAsMethod );
+}
+
+struct NameAndTags {
+ NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
+ StringRef name;
+ StringRef tags;
+};
+
+struct AutoReg : NonCopyable {
+ AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
+ ~AutoReg();
+};
+
+} // end namespace Catch
+
+#if defined(CATCH_CONFIG_DISABLE)
+ #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
+ static void TestName()
+ #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
+ namespace{ \
+ struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
+ void test(); \
+ }; \
+ } \
+ void TestName::test()
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... ) \
+ INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
+ namespace{ \
+ namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
+ INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
+ } \
+ } \
+ INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
+
+ #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ )
+ #else
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
+ #endif
+
+ #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ )
+ #else
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )
+ #endif
+
+ #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
+ #else
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
+ #endif
+
+ #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
+ #else
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
+ #endif
+#endif
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
+ static void TestName(); \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+ static void TestName()
+ #define INTERNAL_CATCH_TESTCASE( ... ) \
+ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), __VA_ARGS__ )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ namespace{ \
+ struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
+ void test(); \
+ }; \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
+ } \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+ void TestName::test()
+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
+ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), ClassName, __VA_ARGS__ )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+ INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
+ namespace {\
+ namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
+ INTERNAL_CATCH_TYPE_GEN\
+ INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
+ INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
+ template \
+ struct TestName{\
+ TestName(){\
+ int index = 0; \
+ constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
+ using expander = int[];\
+ (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
+ }\
+ };\
+ static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+ TestName();\
+ return 0;\
+ }();\
+ }\
+ }\
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+ INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ )
+#else
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
+#endif
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ )
+#else
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )
+#endif
+
+ #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+ template static void TestFuncName(); \
+ namespace {\
+ namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
+ INTERNAL_CATCH_TYPE_GEN \
+ INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
+ template \
+ struct TestName { \
+ void reg_tests() { \
+ int index = 0; \
+ using expander = int[]; \
+ constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
+ constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
+ constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */\
+ } \
+ }; \
+ static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
+ using TestInit = typename create()), TypeList>::type; \
+ TestInit t; \
+ t.reg_tests(); \
+ return 0; \
+ }(); \
+ } \
+ } \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+ template \
+ static void TestFuncName()
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+ #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
+ INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T,__VA_ARGS__)
+#else
+ #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T, __VA_ARGS__ ) )
+#endif
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+ #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
+ INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__)
+#else
+ #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )
+#endif
+
+ #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+ template static void TestFunc(); \
+ namespace {\
+ namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
+ INTERNAL_CATCH_TYPE_GEN\
+ template \
+ struct TestName { \
+ void reg_tests() { \
+ int index = 0; \
+ using expander = int[]; \
+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */\
+ } \
+ };\
+ static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
+ using TestInit = typename convert::type; \
+ TestInit t; \
+ t.reg_tests(); \
+ return 0; \
+ }(); \
+ }}\
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+ template \
+ static void TestFunc()
+
+ #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
+ INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, TmplList )
+
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+ namespace {\
+ namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
+ INTERNAL_CATCH_TYPE_GEN\
+ INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
+ INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
+ INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
+ template \
+ struct TestNameClass{\
+ TestNameClass(){\
+ int index = 0; \
+ constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
+ using expander = int[];\
+ (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
+ }\
+ };\
+ static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+ TestNameClass();\
+ return 0;\
+ }();\
+ }\
+ }\
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+ INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
+#else
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
+#endif
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
+#else
+ #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
+#endif
+
+ #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+ template \
+ struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName ) { \
+ void test();\
+ };\
+ namespace {\
+ namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
+ INTERNAL_CATCH_TYPE_GEN \
+ INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
+ template\
+ struct TestNameClass{\
+ void reg_tests(){\
+ int index = 0;\
+ using expander = int[];\
+ constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
+ constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
+ constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */ \
+ }\
+ };\
+ static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+ using TestInit = typename create()), TypeList>::type;\
+ TestInit t;\
+ t.reg_tests();\
+ return 0;\
+ }(); \
+ }\
+ }\
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+ template \
+ void TestName::test()
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+ #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
+ INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )
+#else
+ #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )
+#endif
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+ #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
+ INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )
+#else
+ #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )
+#endif
+
+ #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+ template \
+ struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName ) { \
+ void test();\
+ };\
+ namespace {\
+ namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
+ INTERNAL_CATCH_TYPE_GEN\
+ template\
+ struct TestNameClass{\
+ void reg_tests(){\
+ int index = 0;\
+ using expander = int[];\
+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \
+ }\
+ };\
+ static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+ using TestInit = typename convert::type;\
+ TestInit t;\
+ t.reg_tests();\
+ return 0;\
+ }(); \
+ }}\
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+ template \
+ void TestName::test()
+
+#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
+ INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, TmplList )
+
+// end catch_test_registry.h
+// start catch_capture.hpp
+
+// start catch_assertionhandler.h
+
+// start catch_assertioninfo.h
+
+// start catch_result_type.h
+
+namespace Catch {
+
+ // ResultWas::OfType enum
+ struct ResultWas { enum OfType {
+ Unknown = -1,
+ Ok = 0,
+ Info = 1,
+ Warning = 2,
+
+ FailureBit = 0x10,
+
+ ExpressionFailed = FailureBit | 1,
+ ExplicitFailure = FailureBit | 2,
+
+ Exception = 0x100 | FailureBit,
+
+ ThrewException = Exception | 1,
+ DidntThrowException = Exception | 2,
+
+ FatalErrorCondition = 0x200 | FailureBit
+
+ }; };
+
+ bool isOk( ResultWas::OfType resultType );
+ bool isJustInfo( int flags );
+
+ // ResultDisposition::Flags enum
+ struct ResultDisposition { enum Flags {
+ Normal = 0x01,
+
+ ContinueOnFailure = 0x02, // Failures fail test, but execution continues
+ FalseTest = 0x04, // Prefix expression with !
+ SuppressFail = 0x08 // Failures are reported but do not fail the test
+ }; };
+
+ ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
+
+ bool shouldContinueOnFailure( int flags );
+ inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
+ bool shouldSuppressFailure( int flags );
+
+} // end namespace Catch
+
+// end catch_result_type.h
+namespace Catch {
+
+ struct AssertionInfo
+ {
+ StringRef macroName;
+ SourceLineInfo lineInfo;
+ StringRef capturedExpression;
+ ResultDisposition::Flags resultDisposition;
+
+ // We want to delete this constructor but a compiler bug in 4.8 means
+ // the struct is then treated as non-aggregate
+ //AssertionInfo() = delete;
+ };
+
+} // end namespace Catch
+
+// end catch_assertioninfo.h
+// start catch_decomposer.h
+
+// start catch_tostring.h
+
+#include
+#include
+#include
+#include
+// start catch_stream.h
+
+#include
+#include
+#include
+
+namespace Catch {
+
+ std::ostream& cout();
+ std::ostream& cerr();
+ std::ostream& clog();
+
+ class StringRef;
+
+ struct IStream {
+ virtual ~IStream();
+ virtual std::ostream& stream() const = 0;
+ };
+
+ auto makeStream( StringRef const &filename ) -> IStream const*;
+
+ class ReusableStringStream : NonCopyable {
+ std::size_t m_index;
+ std::ostream* m_oss;
+ public:
+ ReusableStringStream();
+ ~ReusableStringStream();
+
+ auto str() const -> std::string;
+
+ template
+ auto operator << ( T const& value ) -> ReusableStringStream& {
+ *m_oss << value;
+ return *this;
+ }
+ auto get() -> std::ostream& { return *m_oss; }
+ };
+}
+
+// end catch_stream.h
+// start catch_interfaces_enum_values_registry.h
+
+#include
+
+namespace Catch {
+
+ namespace Detail {
+ struct EnumInfo {
+ StringRef m_name;
+ std::vector> m_values;
+
+ ~EnumInfo();
+
+ StringRef lookup( int value ) const;
+ };
+ } // namespace Detail
+
+ struct IMutableEnumValuesRegistry {
+ virtual ~IMutableEnumValuesRegistry();
+
+ virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector const& values ) = 0;
+
+ template
+ Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list values ) {
+ static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
+ std::vector intValues;
+ intValues.reserve( values.size() );
+ for( auto enumValue : values )
+ intValues.push_back( static_cast( enumValue ) );
+ return registerEnum( enumName, allEnums, intValues );
+ }
+ };
+
+} // Catch
+
+// end catch_interfaces_enum_values_registry.h
+
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+#include
+#endif
+
+#ifdef __OBJC__
+// start catch_objc_arc.hpp
+
+#import
+
+#ifdef __has_feature
+#define CATCH_ARC_ENABLED __has_feature(objc_arc)
+#else
+#define CATCH_ARC_ENABLED 0
+#endif
+
+void arcSafeRelease( NSObject* obj );
+id performOptionalSelector( id obj, SEL sel );
+
+#if !CATCH_ARC_ENABLED
+inline void arcSafeRelease( NSObject* obj ) {
+ [obj release];
+}
+inline id performOptionalSelector( id obj, SEL sel ) {
+ if( [obj respondsToSelector: sel] )
+ return [obj performSelector: sel];
+ return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED
+#define CATCH_ARC_STRONG
+#else
+inline void arcSafeRelease( NSObject* ){}
+inline id performOptionalSelector( id obj, SEL sel ) {
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
+#endif
+ if( [obj respondsToSelector: sel] )
+ return [obj performSelector: sel];
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+ return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
+#define CATCH_ARC_STRONG __strong
+#endif
+
+// end catch_objc_arc.hpp
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
+#endif
+
+namespace Catch {
+ namespace Detail {
+
+ extern const std::string unprintableString;
+
+ std::string rawMemoryToString( const void *object, std::size_t size );
+
+ template
+ std::string rawMemoryToString( const T& object ) {
+ return rawMemoryToString( &object, sizeof(object) );
+ }
+
+ template
+ class IsStreamInsertable {
+ template
+ static auto test(int)
+ -> decltype(std::declval() << std::declval(), std::true_type());
+
+ template
+ static auto test(...)->std::false_type;
+
+ public:
+ static const bool value = decltype(test(0))::value;
+ };
+
+ template
+ std::string convertUnknownEnumToString( E e );
+
+ template
+ typename std::enable_if<
+ !std::is_enum::value && !std::is_base_of::value,
+ std::string>::type convertUnstreamable( T const& ) {
+ return Detail::unprintableString;
+ }
+ template
+ typename std::enable_if<
+ !std::is_enum::value && std::is_base_of::value,
+ std::string>::type convertUnstreamable(T const& ex) {
+ return ex.what();
+ }
+
+ template
+ typename std::enable_if<
+ std::is_enum::value
+ , std::string>::type convertUnstreamable( T const& value ) {
+ return convertUnknownEnumToString( value );
+ }
+
+#if defined(_MANAGED)
+ //! Convert a CLR string to a utf8 std::string
+ template
+ std::string clrReferenceToString( T^ ref ) {
+ if (ref == nullptr)
+ return std::string("null");
+ auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
+ cli::pin_ptr p = &bytes[0];
+ return std::string(reinterpret_cast(p), bytes->Length);
+ }
+#endif
+
+ } // namespace Detail
+
+ // If we decide for C++14, change these to enable_if_ts
+ template
+ struct StringMaker {
+ template
+ static
+ typename std::enable_if<::Catch::Detail::IsStreamInsertable::value, std::string>::type
+ convert(const Fake& value) {
+ ReusableStringStream rss;
+ // NB: call using the function-like syntax to avoid ambiguity with
+ // user-defined templated operator<< under clang.
+ rss.operator<<(value);
+ return rss.str();
+ }
+
+ template
+ static
+ typename std::enable_if::value, std::string>::type
+ convert( const Fake& value ) {
+#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
+ return Detail::convertUnstreamable(value);
+#else
+ return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
+#endif
+ }
+ };
+
+ namespace Detail {
+
+ // This function dispatches all stringification requests inside of Catch.
+ // Should be preferably called fully qualified, like ::Catch::Detail::stringify
+ template
+ std::string stringify(const T& e) {
+ return ::Catch::StringMaker::type>::type>::convert(e);
+ }
+
+ template
+ std::string convertUnknownEnumToString( E e ) {
+ return ::Catch::Detail::stringify(static_cast::type>(e));
+ }
+
+#if defined(_MANAGED)
+ template
+ std::string stringify( T^ e ) {
+ return ::Catch::StringMaker::convert(e);
+ }
+#endif
+
+ } // namespace Detail
+
+ // Some predefined specializations
+
+ template<>
+ struct StringMaker {
+ static std::string convert(const std::string& str);
+ };
+
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+ template<>
+ struct StringMaker {
+ static std::string convert(std::string_view str);
+ };
+#endif
+
+ template<>
+ struct StringMaker {
+ static std::string convert(char const * str);
+ };
+ template<>
+ struct StringMaker {
+ static std::string convert(char * str);
+ };
+
+#ifdef CATCH_CONFIG_WCHAR
+ template<>
+ struct StringMaker {
+ static std::string convert(const std::wstring& wstr);
+ };
+
+# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+ template<>
+ struct StringMaker {
+ static std::string convert(std::wstring_view str);
+ };
+# endif
+
+ template<>
+ struct StringMaker {
+ static std::string convert(wchar_t const * str);
+ };
+ template<>
+ struct StringMaker {
+ static std::string convert(wchar_t * str);
+ };
+#endif
+
+ // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
+ // while keeping string semantics?
+ template
+ struct StringMaker {
+ static std::string convert(char const* str) {
+ return ::Catch::Detail::stringify(std::string{ str });
+ }
+ };
+ template
+ struct StringMaker {
+ static std::string convert(signed char const* str) {
+ return ::Catch::Detail::stringify(std::string{ reinterpret_cast(str) });
+ }
+ };
+ template
+ struct StringMaker {
+ static std::string convert(unsigned char const* str) {
+ return ::Catch::Detail::stringify(std::string{ reinterpret_cast(str) });
+ }
+ };
+
+#if defined(CATCH_CONFIG_CPP17_BYTE)
+ template<>
+ struct StringMaker {
+ static std::string convert(std::byte value);
+ };
+#endif // defined(CATCH_CONFIG_CPP17_BYTE)
+ template<>
+ struct StringMaker {
+ static std::string convert(int value);
+ };
+ template<>
+ struct StringMaker {
+ static std::string convert(long value);
+ };
+ template<>
+ struct StringMaker {
+ static std::string convert(long long value);
+ };
+ template<>
+ struct StringMaker {
+ static std::string convert(unsigned int value);
+ };
+ template<>
+ struct StringMaker {
+ static std::string convert(unsigned long value);
+ };
+ template<>
+ struct StringMaker {
+ static std::string convert(unsigned long long value);
+ };
+
+ template<>
+ struct StringMaker {
+ static std::string convert(bool b);
+ };
+
+ template<>
+ struct StringMaker {
+ static std::string convert(char c);
+ };
+ template<>
+ struct StringMaker {
+ static std::string convert(signed char c);
+ };
+ template<>
+ struct StringMaker {
+ static std::string convert(unsigned char c);
+ };
+
+ template<>
+ struct StringMaker {
+ static std::string convert(std::nullptr_t);
+ };
+
+ template<>
+ struct StringMaker {
+ static std::string convert(float value);
+ static int precision;
+ };
+
+ template<>
+ struct StringMaker {
+ static std::string convert(double value);
+ static int precision;
+ };
+
+ template
+ struct StringMaker {
+ template