diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 00c21e2..7aedf70 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -23,10 +23,10 @@ jobs: run: sudo apt update && sudo apt install libboost-all-dev libcurl4-gnutls-dev libfmt-dev libgtest-dev iputils-ping - name: test_docker run: docker version && docker info - - name: build_images - run: cd images && sh create_images.sh - name: setup_project run: git submodule update --init --recursive + - name: build_images + run: cd third_party/senjun-images && sh create_images.sh - name: configure_project run: cmake -B build -DBUILD_TESTING=TRUE - name: build_project diff --git a/.gitmodules b/.gitmodules index a503679..957b496 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,4 +4,7 @@ branch = master [submodule "third_party/structarus"] path = third_party/structarus - url = https://github.com/senjun-team/structarus \ No newline at end of file + url = https://github.com/senjun-team/structarus +[submodule "third_party/senjun-images"] + path = third_party/senjun-images + url = https://github.com/senjun-team/senjun-images.git diff --git a/images/cpp/Dockerfile b/images/cpp/Dockerfile deleted file mode 100644 index c125d83..0000000 --- a/images/cpp/Dockerfile +++ /dev/null @@ -1,36 +0,0 @@ -FROM silkeh/clang:19 -LABEL ru.senjun.image.authors="Shipilov Dmitry" - -RUN apt-get update \ - && apt install -y ninja-build \ - && apt-get purge -y cmake - -ARG CMAKE_VERSION=3.31.2 - -RUN wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-Linux-x86_64.sh \ - -q -O /tmp/cmake-install.sh \ - && chmod u+x /tmp/cmake-install.sh \ - && mkdir /usr/bin/cmake \ - && /tmp/cmake-install.sh --skip-license --prefix=/usr/bin/cmake \ - && rm /tmp/cmake-install.sh - -ENV PATH="/usr/bin/cmake/bin:${PATH}" - -WORKDIR /home/code_runner - -# Directory for task launching -RUN mkdir /home/code_runner/task -COPY task/run-task.sh task/CMakeLists.txt task/ut.hpp /home/code_runner/task/ - -# Directory for playground -RUN mkdir /home/code_runner/playground -COPY playground/run-playground.sh /home/code_runner/playground - -# Change access write for code_runner home directory to root recursively -RUN useradd -ms /bin/bash code_runner \ - && chown -R code_runner:code_runner /home/code_runner \ - && chmod -R 1750 /home/code_runner - -USER code_runner - -ENTRYPOINT ["bash"] diff --git a/images/cpp/build_image.sh b/images/cpp/build_image.sh deleted file mode 100644 index 0fa6403..0000000 --- a/images/cpp/build_image.sh +++ /dev/null @@ -1 +0,0 @@ -docker build -t senjun_cpp . \ No newline at end of file diff --git a/images/cpp/playground/run-playground.sh b/images/cpp/playground/run-playground.sh deleted file mode 100644 index 6ffd30b..0000000 --- a/images/cpp/playground/run-playground.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash - -# parse flags - single letters prefixed with hyphen before each argument -# example: sh run.sh -f project_dir -while getopts f: flag -do - case "${flag}" in - f) project=${OPTARG};; - esac -done - -f="$(basename -- $project)" - -cd /home/code_runner/playground/$f - -# configure project -if ! ( timeout 5s cmake -Bbuild -Wno-dev -GNinja > /tmp/configure.txt ); then - cat /tmp/configure.txt - echo user_solution_error_f936a25e - exit -fi - -# build cpp project -if ! ( timeout 10s cmake --build build/ -- -j4 > /tmp/build.txt ); then - cat /tmp/build.txt - echo user_solution_error_f936a25e - exit -fi - -# run cpp project -if ! ( timeout 5s ./build/cpp_experiments ); then - echo user_solution_error_f936a25e - exit -fi - -echo user_solution_ok_f936a25e diff --git a/images/cpp/task/CMakeLists.txt b/images/cpp/task/CMakeLists.txt deleted file mode 100644 index fc14cd8..0000000 --- a/images/cpp/task/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -cmake_minimum_required(VERSION 3.30.0 FATAL_ERROR) - -# Включаем флаг для возможности `import std`. -# Эта строка должна идти ДО объявления, что проект на C++ (значение CXX). -SET(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508") - -# Для всех целей сборки устанавливаем возможность импорта std в 1. -SET(CMAKE_CXX_MODULE_STD 1) - -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -Werror -Wall") - -PROJECT(task_solution LANGUAGES CXX) - -# TODO hardcode path is fragile! -IF (EXISTS "/home/code_runner/task/main.cpp") - add_executable(main) - - target_sources(main - PRIVATE - main.cpp) - - target_compile_features(main - PRIVATE cxx_std_23 - INTERFACE cxx_std_23) -ENDIF() - -add_executable(tests) - -target_sources(tests - PRIVATE - tests.cpp) - -target_compile_features(tests - PRIVATE cxx_std_23 - INTERFACE cxx_std_23) diff --git a/images/cpp/task/run-task.sh b/images/cpp/task/run-task.sh deleted file mode 100644 index 101334f..0000000 --- a/images/cpp/task/run-task.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash - -# parse flags - single letters prefixed fith hyphen before each argument -# example: sh run.sh -f task -while getopts f:v: flag -do - case "${flag}" in - f) file=${OPTARG};; - v) task_type=${OPTARG};; - esac -done - -# go to the task dir -cd /home/code_runner/task - -# if exists file with user code -if [ $task_type = "code" ]; then - touch main.cpp - cp $file main.cpp -fi - -cp ${file}_tests tests.cpp - -# configure project -if ! ( timeout 10s cmake -Wno-dev -Bbuild -GNinja > /tmp/configure.txt ); then - cat /tmp/configure.txt - echo user_solution_error_f936a25e - exit -fi - -# build cpp project -if ! ( timeout 20s cmake --build build/ -- -j4 > /tmp/build.txt ); then - cat /tmp/build.txt - echo user_solution_error_f936a25e - exit -fi - -# check task "what will this code output?" -if [ $task_type = "code" ]; then - if ! ( timeout 4s ./build/main ); then - echo user_solution_error_f936a25e - exit - fi -fi - -echo user_code_ok_f936a25e - -if ! ( timeout 4s ./build/tests ); then - echo tests_cases_error_f936a25e - exit -fi - -echo user_solution_ok_f936a25e \ No newline at end of file diff --git a/images/cpp/task/ut.hpp b/images/cpp/task/ut.hpp deleted file mode 100644 index 51f8577..0000000 --- a/images/cpp/task/ut.hpp +++ /dev/null @@ -1,3345 +0,0 @@ -// -// Copyright (c) 2019-2021 Kris Jusiak (kris at jusiak dot net) -// -// 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) -// -#if defined(__cpp_modules) && !defined(BOOST_UT_DISABLE_MODULE) -export module boost.ut; -export import std; -#define BOOST_UT_EXPORT export -#else -#pragma once -#define BOOST_UT_EXPORT -#endif - -#if __has_include() -#include // and, or, not, ... -#endif - -#include -#if defined(_MSC_VER) -#pragma push_macro("min") -#pragma push_macro("max") -#undef min -#undef max -#endif -// Before libc++ 17 had experimental support for format and it required a -// special build flag. Currently libc++ has not implemented all C++20 chrono -// improvements. Therefore doesn't define __cpp_lib_format, instead query the -// library version to detect the support status. -// -// MSVC STL and libstdc++ provide __cpp_lib_format. -#if defined(__cpp_lib_format) or \ - (defined(_LIBCPP_VERSION) and _LIBCPP_VERSION >= 170000) -#define BOOST_UT_HAS_FORMAT -#endif - -#if not defined(__cpp_rvalue_references) -#error "[Boost::ext].UT requires support for rvalue references"; -#elif not defined(__cpp_decltype) -#error "[Boost::ext].UT requires support for decltype"; -#elif not defined(__cpp_return_type_deduction) -#error "[Boost::ext].UT requires support for return type deduction"; -#elif not defined(__cpp_deduction_guides) -#error "[Boost::ext].UT requires support for return deduction guides"; -#elif not defined(__cpp_generic_lambdas) -#error "[Boost::ext].UT requires support for generic lambdas"; -#elif not defined(__cpp_constexpr) -#error "[Boost::ext].UT requires support for constexpr"; -#elif not defined(__cpp_alias_templates) -#error "[Boost::ext].UT requires support for alias templates"; -#elif not defined(__cpp_variadic_templates) -#error "[Boost::ext].UT requires support for variadic templates"; -#elif not defined(__cpp_fold_expressions) -#error "[Boost::ext].UT requires support for return fold expressions"; -#elif not defined(__cpp_static_assert) -#error "[Boost::ext].UT requires support for static assert"; -#else -#define BOOST_UT_VERSION 2'1'1 - -#if defined(__has_builtin) and defined(__GNUC__) and (__GNUC__ < 10) and \ - not defined(__clang__) -#undef __has_builtin -#endif - -#if not defined(__has_builtin) -#if defined(__GNUC__) and (__GNUC__ >= 9) -#define __has___builtin_FILE 1 -#define __has___builtin_LINE 1 -#endif -#define __has_builtin(...) __has_##__VA_ARGS__ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if __has_include() and __has_include() -#include -#include -#endif -#if defined(__cpp_exceptions) -#include -#endif - -#if __has_include() -#include -#endif -#if __has_include() -#include -#endif - -struct unique_name_for_auto_detect_prefix_and_suffix_length_0123456789_struct_ { -}; - -BOOST_UT_EXPORT -namespace boost::inline ext::ut::inline v2_1_1 { -namespace utility { -template -class function; -template -class function { - public: - constexpr function() = default; - template - constexpr /*explicit(false)*/ function(T data) - : invoke_{invoke_impl}, - destroy_{destroy_impl}, - data_{new T{static_cast(data)}} {} - constexpr function(function&& other) noexcept - : invoke_{static_cast(other.invoke_)}, - destroy_{static_cast(other.destroy_)}, - data_{static_cast(other.data_)} { - other.data_ = {}; - } - constexpr function(const function&) = delete; - ~function() { destroy_(data_); } - - constexpr function& operator=(const function&) = delete; - constexpr function& operator=(function&&) = delete; - [[nodiscard]] constexpr auto operator()(TArgs... args) -> R { - return invoke_(data_, args...); - } - [[nodiscard]] constexpr auto operator()(TArgs... args) const -> R { - return invoke_(data_, args...); - } - - private: - template - [[nodiscard]] static auto invoke_impl(void* data, TArgs... args) -> R { - return (*static_cast(data))(args...); - } - - template - static auto destroy_impl(void* data) -> void { - delete static_cast(data); - } - - R (*invoke_)(void*, TArgs...){}; - void (*destroy_)(void*){}; - void* data_{}; -}; - -[[nodiscard]] inline auto is_match(std::string_view input, - std::string_view pattern) -> bool { - if (std::empty(pattern)) { - return std::empty(input); - } - - if (std::empty(input)) { - return pattern[0] == '*' ? is_match(input, pattern.substr(1)) : false; - } - - if (pattern[0] != '?' and pattern[0] != '*' and pattern[0] != input[0]) { - return false; - } - - if (pattern[0] == '*') { - for (decltype(std::size(input)) i = 0u; i <= std::size(input); ++i) { - if (is_match(input.substr(i), pattern.substr(1))) { - return true; - } - } - return false; - } - - return is_match(input.substr(1), pattern.substr(1)); -} - -template -[[nodiscard]] constexpr auto match(const TPattern& pattern, - const TStr& str) -> std::vector { - std::vector groups{}; - auto pi = 0u; - auto si = 0u; - - const auto matcher = [&](char b, char e, char c = 0) { - const auto match = si; - while (str[si] and str[si] != b and str[si] != c) { - ++si; - } - groups.emplace_back(str.substr(match, si - match)); - while (pattern[pi] and pattern[pi] != e) { - ++pi; - } - pi++; - }; - - while (pi < std::size(pattern) && si < std::size(str)) { - if (pattern[pi] == '\'' and str[si] == '\'' and pattern[pi + 1] == '{') { - ++si; - matcher('\'', '}'); - } else if (pattern[pi] == '{') { - matcher(' ', '}', ','); - } else if (pattern[pi] != str[si]) { - return {}; - } - ++pi; - ++si; - } - - if (si < str.size() or pi < std::size(pattern)) { - return {}; - } - - return groups; -} - -template -[[nodiscard]] inline auto split(T input, TDelim delim) -> std::vector { - std::vector output{}; - std::size_t first{}; - while (first < std::size(input)) { - const auto second = input.find_first_of(delim, first); - if (first != second) { - output.emplace_back(input.substr(first, second - first)); - } - if (second == T::npos) { - break; - } - first = second + 1; - } - return output; -} -constexpr auto regex_match(const char* str, const char* pattern) -> bool { - if (*pattern == '\0' && *str == '\0') return true; - if (*pattern == '\0' && *str != '\0') return false; - if (*str == '\0' && *pattern != '\0') return false; - if (*pattern == '.') { - return regex_match(str + 1, pattern + 1); - } - if (*pattern == *str) { - return regex_match(str + 1, pattern + 1); - } - return false; -} -} // namespace utility - -namespace reflection { -#if defined(__cpp_lib_source_location) && !defined(_LIBCPP_APPLE_CLANG_VER) -using source_location = std::source_location; -#else -class source_location { - public: - [[nodiscard]] static constexpr auto current( -#if (__has_builtin(__builtin_FILE) and __has_builtin(__builtin_LINE)) - const char* file = __builtin_FILE(), int line = __builtin_LINE() -#else - const char* file = "unknown", int line = {} -#endif - ) noexcept { - source_location sl{}; - sl.file_ = file; - sl.line_ = line; - return sl; - } - [[nodiscard]] constexpr auto file_name() const noexcept { return file_; } - [[nodiscard]] constexpr auto line() const noexcept { return line_; } - - private: - const char* file_{"unknown"}; - int line_{}; -}; -#endif -namespace detail { -template -[[nodiscard]] constexpr auto get_template_function_name_use_type() - -> const std::string_view { -// for over compiler need over macros -#if defined(_MSC_VER) && !defined(__clang__) - return {&__FUNCSIG__[0], sizeof(__FUNCSIG__)}; -#else - return {&__PRETTY_FUNCTION__[0], sizeof(__PRETTY_FUNCTION__)}; -#endif -} - -// decay allows you to highlight a cleaner name -template -[[nodiscard]] constexpr auto get_template_function_name_use_decay_type() - -> const std::string_view { - return get_template_function_name_use_type>(); -} - -inline constexpr const std::string_view raw_type_name = - get_template_function_name_use_decay_type< - unique_name_for_auto_detect_prefix_and_suffix_length_0123456789_struct_>(); - -inline constexpr const std::size_t raw_length = raw_type_name.length(); -inline constexpr const std::string_view need_name = -#if defined(_MSC_VER) and not defined(__clang__) - "struct " - "unique_name_for_auto_detect_prefix_and_suffix_length_0123456789_struct_"; -#else - "unique_name_for_auto_detect_prefix_and_suffix_length_0123456789_struct_"; -#endif -inline constexpr const std::size_t need_length = need_name.length(); -static_assert(need_length <= raw_length, - "Auto find prefix and suffix length broken error 1"); -inline constexpr const std::size_t prefix_length = - raw_type_name.find(need_name); -static_assert(prefix_length != std::string_view::npos, - "Auto find prefix and suffix length broken error 2"); -static_assert(prefix_length <= raw_length, - "Auto find prefix and suffix length broken error 3"); -inline constexpr const std::size_t tail_length = raw_length - prefix_length; -static_assert(need_length <= tail_length, - "Auto find prefix and suffix length broken error 4"); -inline constexpr const std::size_t suffix_length = tail_length - need_length; - -} // namespace detail - -template -[[nodiscard]] constexpr auto type_name() -> const std::string_view { - const std::string_view raw_type_name = - detail::get_template_function_name_use_type(); - const std::size_t end = raw_type_name.length() - detail::suffix_length; - const std::size_t len = end - detail::prefix_length; - std::string_view result = raw_type_name.substr(detail::prefix_length, len); - return result; -} - -// decay allows you to highlight a cleaner name -template -[[nodiscard]] constexpr auto decay_type_name() -> const std::string_view { - const std::string_view raw_type_name = - detail::get_template_function_name_use_decay_type(); - const std::size_t end = raw_type_name.length() - detail::suffix_length; - const std::size_t len = end - detail::prefix_length; - std::string_view result = raw_type_name.substr(detail::prefix_length, len); - return result; -} -} // namespace reflection - -namespace math { -template -[[nodiscard]] constexpr auto abs(const T t) -> T { - return t < T{} ? -t : t; -} - -template -[[nodiscard]] constexpr auto abs_diff(const T t, - const U u) -> decltype(t < u ? u - t - : t - u) { - return t < u ? u - t : t - u; -} - -template -[[nodiscard]] constexpr auto min_value(const T& lhs, const T& rhs) -> const T& { - return (rhs < lhs) ? rhs : lhs; -} - -template -[[nodiscard]] constexpr auto pow(const T base, const TExp exp) -> T { - return exp ? T(base * pow(base, exp - TExp(1))) : T(1); -} - -template -[[nodiscard]] constexpr auto num() -> T { - static_assert( - ((Cs == '.' or Cs == '\'' or (Cs >= '0' and Cs <= '9')) and ...)); - T result{}; - for (const char c : std::array{Cs...}) { - if (c == '.') { - break; - } - if (c >= '0' and c <= '9') { - result = result * T(10) + T(c - '0'); - } - } - return result; -} - -template -[[nodiscard]] constexpr auto den() -> T { - constexpr const std::array cs{Cs...}; - T result{}; - auto i = 0u; - while (cs[i++] != '.') { - } - - for (auto j = i; j < sizeof...(Cs); ++j) { - result += pow(T(10), sizeof...(Cs) - j) * T(cs[j] - '0'); - } - return result; -} - -template -[[nodiscard]] constexpr auto den_size() -> T { - constexpr const std::array cs{Cs...}; - T i{}; - while (cs[i++] != '.') { - } - - return T(sizeof...(Cs)) - i + T(1); -} - -template -[[nodiscard]] constexpr auto den_size(TValue value) -> T { - constexpr auto precision = TValue(1e-7); - T result{}; - TValue tmp{}; - do { - value *= 10; - tmp = value - T(value); - ++result; - } while (tmp > precision); - - return result; -} - -} // namespace math - -namespace type_traits { -template -struct list {}; - -template -struct identity { - using type = T; -}; - -template -struct function_traits : function_traits {}; - -template -struct function_traits { - using result_type = R; - using args = list; -}; - -template -struct function_traits { - using result_type = R; - using args = list; -}; - -template -struct function_traits { - using result_type = R; - using args = list; -}; - -template -struct function_traits { - using result_type = R; - using args = list; -}; - -template -T&& declval(); -template -constexpr auto is_valid(TExpr expr) -> decltype(expr(declval()), - bool()) { - return true; -} -template -constexpr auto is_valid(...) -> bool { - return false; -} - -template -inline constexpr auto is_range_v = - is_valid([](auto t) -> decltype(t.begin(), t.end(), void()) {}); - -template -inline constexpr auto has_user_print = is_valid( - [](auto t) -> decltype(void(declval() << t)) {}); - -template -struct has_static_member_object_value : std::false_type {}; - -template -struct has_static_member_object_value().value)>> - : std::bool_constant && - !std::is_function_v> {}; - -template -inline constexpr bool has_static_member_object_value_v = - has_static_member_object_value::value; - -template -struct has_static_member_object_epsilon : std::false_type {}; - -template -struct has_static_member_object_epsilon< - T, std::void_t().epsilon)>> - : std::bool_constant && - !std::is_function_v> {}; - -template -inline constexpr bool has_static_member_object_epsilon_v = - has_static_member_object_epsilon::value; - -template -inline constexpr auto is_floating_point_v = false; -template <> -inline constexpr auto is_floating_point_v = true; -template <> -inline constexpr auto is_floating_point_v = true; -template <> -inline constexpr auto is_floating_point_v = true; - -#if defined(__clang__) or defined(_MSC_VER) -template -inline constexpr auto is_convertible_v = __is_convertible_to(From, To); -#else -template -constexpr auto is_convertible(int) -> decltype(bool(To(declval()))) { - return true; -} -template -constexpr auto is_convertible(...) { - return false; -} -template -constexpr auto is_convertible_v = is_convertible(0); -#endif - -template -struct requires_ {}; -template <> -struct requires_ { - using type = int; -}; - -template -using requires_t = typename requires_::type; -} // namespace type_traits - -template -struct fixed_string { - constexpr static std::size_t N = SIZE; - CharT _data[N + 1] = {}; - - constexpr explicit(false) fixed_string(const CharT (&str)[N + 1]) noexcept { - if constexpr (N != 0) - for (std::size_t i = 0; i < N; ++i) _data[i] = str[i]; - } - - [[nodiscard]] constexpr std::size_t size() const noexcept { return N; } - [[nodiscard]] constexpr bool empty() const noexcept { return N == 0; } - [[nodiscard]] constexpr explicit operator std::string_view() const noexcept { - return {_data, N}; - } - [[nodiscard]] explicit operator std::string() const noexcept { - return {_data, N}; - } - [[nodiscard]] operator const char*() const noexcept { return _data; } - [[nodiscard]] constexpr bool operator==( - const fixed_string& other) const noexcept { - return std::string_view{_data, N} == std::string_view(other); - } - - template - [[nodiscard]] friend constexpr bool operator==( - const fixed_string&, const fixed_string&) { - return false; - } -}; - -template -fixed_string(const CharT (&str)[N]) -> fixed_string; - -struct none {}; - -namespace events { -struct run_begin { - int argc{}; - const char** argv{}; -}; -struct test_begin { - std::string_view type{}; - std::string_view name{}; - reflection::source_location location{}; -}; -struct suite_begin { - std::string_view type{}; - std::string_view name{}; - reflection::source_location location{}; -}; -struct suite_end { - std::string_view type{}; - std::string_view name{}; - reflection::source_location location{}; -}; -template -struct test { - std::string_view type{}; - std::string name{}; /// might be dynamic - std::vector tag{}; - reflection::source_location location{}; - TArg arg{}; - Test run{}; - - constexpr auto operator()() { run_impl(static_cast(run), arg); } - constexpr auto operator()() const { run_impl(static_cast(run), arg); } - - private: - static constexpr auto run_impl(Test test, const none&) { test(); } - - template - static constexpr auto run_impl(T test, const TArg& arg) -> decltype(test(arg), - void()) { - test(arg); - } - - template - static constexpr auto run_impl(T test, const TArg&) - -> decltype(test.template operator()(), void()) { - test.template operator()(); - } -}; -template -test(std::string_view, std::string_view, std::string_view, - reflection::source_location, TArg, Test) -> test; -template -struct suite { - TSuite run{}; - std::string_view name{}; - constexpr auto operator()() { run(); } - constexpr auto operator()() const { run(); } -}; -template -suite(TSuite) -> suite; -struct test_run { - std::string_view type{}; - std::string_view name{}; -}; -struct test_finish { - std::string_view type{}; - std::string_view name{}; -}; -template -struct skip { - std::string_view type{}; - std::string_view name{}; - TArg arg{}; -}; -template -skip(std::string_view, std::string_view, TArg) -> skip; -struct test_skip { - std::string_view type{}; - std::string_view name{}; -}; -template -struct assertion { - TExpr expr{}; - reflection::source_location location{}; -}; -template -assertion(TExpr, reflection::source_location) -> assertion; -template -struct assertion_pass { - TExpr expr{}; - reflection::source_location location{}; -}; -template -assertion_pass(TExpr) -> assertion_pass; -template -struct assertion_fail { - TExpr expr{}; - reflection::source_location location{}; -}; -template -assertion_fail(TExpr) -> assertion_fail; -struct test_end { - std::string_view type{}; - std::string_view name{}; -}; -template -struct log { - TMsg msg{}; -}; -template -log(TMsg) -> log; -struct fatal_assertion {}; -struct exception { - const char* msg{}; - [[nodiscard]] auto what() const -> const char* { return msg; } -}; -struct summary {}; -} // namespace events - -namespace detail { -struct op {}; - -template -struct fatal_; - -struct fatal { - template - [[nodiscard]] inline auto operator()(const T& t) const { - return detail::fatal_{t}; - } -}; -struct cfg { - using value_ref = std::variant, - std::reference_wrapper, - std::reference_wrapper>; - using option = std::tuple; - static inline reflection::source_location location{}; - static inline bool wip{}; - -#if defined(_MSC_VER) - static inline int largc = __argc; - static inline const char** largv = const_cast(__argv); -#else - static inline int largc = 0; - static inline const char** largv = nullptr; -#endif - - static inline std::string executable_name = "unknown executable"; - static inline std::string query_pattern = ""; // <- done - static inline bool invert_query_pattern = false; // <- done - static inline std::string query_regex_pattern = ""; // <- done - static inline bool show_help = false; // <- done - static inline bool show_tests = false; // <- done - static inline bool list_tags = false; // <- done - static inline bool show_successful_tests = false; // <- done - static inline std::string output_filename = ""; - static inline std::string use_reporter = "console"; // <- done - static inline std::string suite_name = ""; - static inline bool abort_early = false; // <- done - static inline std::size_t abort_after_n_failures = - std::numeric_limits::max(); // <- done - static inline bool show_duration = false; // <- done - static inline std::size_t show_min_duration = 0; - static inline std::string input_filename = ""; - static inline bool show_test_names = false; // <- done - static inline bool show_reporters = false; // <- done - static inline std::string sort_order = "decl"; - static inline std::size_t rnd_seed = 0; // 0: use time - static inline std::string use_colour = "yes"; // <- done - static inline bool show_lib_identity = false; // <- done - static inline std::string wait_for_keypress = "never"; - - static inline const std::vector