diff --git a/src/catch2/internal/catch_enforce.cpp b/src/catch2/internal/catch_enforce.cpp index 4bc47ce3d3..67f2e41d92 100644 --- a/src/catch2/internal/catch_enforce.cpp +++ b/src/catch2/internal/catch_enforce.cpp @@ -9,6 +9,7 @@ #include #include +#include namespace Catch { @@ -36,6 +37,11 @@ namespace Catch { throw_exception(std::runtime_error(msg)); } + [[noreturn]] + void throw_system_error(int ev, const std::error_category& ecat) { + throw_exception(std::system_error(ev, ecat)); + } + } // namespace Catch; diff --git a/src/catch2/internal/catch_enforce.hpp b/src/catch2/internal/catch_enforce.hpp index db52a0e2d2..6ec810fc44 100644 --- a/src/catch2/internal/catch_enforce.hpp +++ b/src/catch2/internal/catch_enforce.hpp @@ -32,6 +32,8 @@ namespace Catch { void throw_domain_error(std::string const& msg); [[noreturn]] void throw_runtime_error(std::string const& msg); + [[noreturn]] + void throw_system_error(int ev, const std::error_category& ecat); } // namespace Catch; @@ -47,6 +49,9 @@ namespace Catch { #define CATCH_RUNTIME_ERROR(...) \ Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ )) +#define CATCH_SYSTEM_ERROR(ev, ecat) \ + Catch::throw_system_error((ev), (ecat)) + #define CATCH_ENFORCE( condition, ... ) \ do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false) diff --git a/src/catch2/internal/catch_output_redirect.cpp b/src/catch2/internal/catch_output_redirect.cpp index 83bcdcd2ee..105e100227 100644 --- a/src/catch2/internal/catch_output_redirect.cpp +++ b/src/catch2/internal/catch_output_redirect.cpp @@ -14,6 +14,7 @@ #include #if defined(CATCH_CONFIG_NEW_CAPTURE) + #include #include #if defined(_MSC_VER) #include // _O_TEXT @@ -67,7 +68,7 @@ inline void close_or_throw(int descriptor) { if (close(descriptor)) { - throw std::system_error{ errno, std::generic_category() }; + CATCH_SYSTEM_ERROR(errno, std::generic_category()); } } @@ -77,7 +78,7 @@ inline int dup_or_throw(int descriptor) if (result == -1) { - throw std::system_error{ errno, std::generic_category() }; + CATCH_SYSTEM_ERROR(errno, std::generic_category()); } return result; @@ -89,7 +90,7 @@ inline int dup2_or_throw(int sourceDescriptor, int destinationDescriptor) if (result == -1) { - throw std::system_error{ errno, std::generic_category() }; + CATCH_SYSTEM_ERROR(errno, std::generic_category()); } return result; @@ -101,7 +102,7 @@ inline int fileno_or_throw(std::FILE* file) if (result == -1) { - throw std::system_error{ errno, std::generic_category() }; + CATCH_SYSTEM_ERROR(errno, std::generic_category()); } return result; @@ -119,7 +120,7 @@ inline void pipe_or_throw(int descriptors[2]) if (result) { - throw std::system_error{ errno, std::generic_category() }; + CATCH_SYSTEM_ERROR(errno, std::generic_category()); } } @@ -133,7 +134,7 @@ inline size_t read_or_throw(int descriptor, void* buffer, size_t size) if (result == -1) { - throw std::system_error{ errno, std::generic_category() }; + CATCH_SYSTEM_ERROR(errno, std::generic_category()); } return static_cast(result); @@ -143,14 +144,14 @@ inline void fflush_or_throw(std::FILE* file) { if (std::fflush(file)) { - throw std::system_error{ errno, std::generic_category() }; + CATCH_SYSTEM_ERROR(errno, std::generic_category()); } } jthread::jthread() noexcept : m_thread{} {} template -jthread::jthread(F&& f, Args&&... args) : m_thread{ std::forward(f), std::forward(args)... } {} +jthread::jthread(F&& f, Args&&... args) : m_thread{ CATCH_FORWARD(f), CATCH_FORWARD(args)... } {} // Not exactly like std::jthread, but close enough for the code below. jthread::~jthread() noexcept @@ -237,8 +238,8 @@ OutputFileRedirector::OutputFileRedirector(FILE* file, std::string& result) : // Anonymous pipes have a limited buffer and require an active reader to ensure the writer does not become blocked. // Use a separate thread to ensure the buffer does not get stuck full. - m_readThread = jthread{ [readDescriptor{ std::move(readDescriptor) }, &result] () mutable { - read_thread(std::move(readDescriptor), result); } }; + m_readThread = jthread{ [readDescriptor{ CATCH_MOVE(readDescriptor) }, &result] () mutable { + read_thread(CATCH_MOVE(readDescriptor), result); } }; dup2_or_throw(writeDescriptor.get(), m_fd); }