mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-01-11 03:00:16 +01:00
rx/die: add die handler & fix make_format_args for fmt library
This commit is contained in:
parent
498b580345
commit
0d049f7566
|
|
@ -1,26 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include "format-base.hpp"
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
namespace rx {
|
||||
using DieHandler =
|
||||
std::function<void(std::string_view text, std::source_location location)>;
|
||||
|
||||
void setDieHandler(DieHandler handler);
|
||||
|
||||
namespace detail {
|
||||
[[noreturn]] void dieImpl(std::string_view fmt, format_args args,
|
||||
std::source_location location);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
[[noreturn]] void die(rx::format_string_with_location<Args...> fmt,
|
||||
[[noreturn]] void die(format_string_with_location<Args...> fmt,
|
||||
const Args &...args) {
|
||||
detail::dieImpl(fmt.get(), make_format_args(const_cast<Args &>(args)...),
|
||||
fmt.location);
|
||||
detail::dieImpl(fmt.get(), rx::make_format_args(args...), fmt.location);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void dieIf(bool condition, rx::format_string_with_location<Args...> fmt,
|
||||
void dieIf(bool condition, format_string_with_location<Args...> fmt,
|
||||
const Args &...args) {
|
||||
if (condition) {
|
||||
detail::dieImpl(fmt.get(), make_format_args(const_cast<Args &>(args)...),
|
||||
fmt.location);
|
||||
detail::dieImpl(fmt.get(), rx::make_format_args(args...), fmt.location);
|
||||
}
|
||||
}
|
||||
} // namespace rx
|
||||
|
|
|
|||
|
|
@ -41,15 +41,27 @@ struct format_string_impl : fmt::format_string<Args...> {
|
|||
return std::string_view(this->str);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> struct make_format_arg_type {
|
||||
using type = T &;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
requires requires(const T &arg) { fmt::make_format_args(arg); }
|
||||
struct make_format_arg_type<T> {
|
||||
using type = const T &;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename... Args>
|
||||
using format_string = std::type_identity_t<detail::format_string_impl<Args...>>;
|
||||
|
||||
template <typename... Args>
|
||||
auto make_format_args(const Args &...args)
|
||||
-> decltype(fmt::make_format_args(const_cast<Args &>(args)...)) {
|
||||
return fmt::make_format_args(const_cast<Args &>(args)...);
|
||||
auto make_format_args(const Args &...args) -> decltype(fmt::make_format_args(
|
||||
const_cast<detail::make_format_arg_type<Args>::type>(args)...)) {
|
||||
return fmt::make_format_args(
|
||||
const_cast<detail::make_format_arg_type<Args>::type>(args)...);
|
||||
}
|
||||
|
||||
using fmt::format_to;
|
||||
|
|
|
|||
|
|
@ -173,6 +173,8 @@ constexpr auto calcFieldCount() {
|
|||
return static_cast<std::size_t>(EnumT::_count);
|
||||
} else if constexpr (requires { EnumT::count; }) {
|
||||
return static_cast<std::size_t>(EnumT::count);
|
||||
} else if constexpr (requires { EnumT::_last; }) {
|
||||
return static_cast<std::size_t>(EnumT::_last) + 1;
|
||||
} else if constexpr (!requires { getNameOf<EnumT(N)>()[0]; }) {
|
||||
if constexpr (requires { getNameOf<EnumT(N + 1)>()[0]; }) {
|
||||
if constexpr (constexpr auto c = getNameOf<EnumT(N + 1)>()[0];
|
||||
|
|
|
|||
|
|
@ -1,18 +1,35 @@
|
|||
#include "die.hpp"
|
||||
|
||||
#include "print.hpp"
|
||||
#include "format-base.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <rx/print.hpp>
|
||||
|
||||
|
||||
static rx::DieHandler g_dieHandler;
|
||||
|
||||
void rx::setDieHandler(DieHandler handler) {
|
||||
g_dieHandler = std::move(handler);
|
||||
}
|
||||
|
||||
void rx::detail::dieImpl(std::string_view fmt, format_args args,
|
||||
std::source_location location) {
|
||||
rx::print(stderr, "\n");
|
||||
rx::print(stderr, "{}:{}:{}: ", location.file_name(), location.line(),
|
||||
location.column());
|
||||
rx::vprint_nonunicode(stderr, fmt, args);
|
||||
rx::print(stderr, "\n");
|
||||
if (g_dieHandler != nullptr) {
|
||||
rx::print(stderr, "\n");
|
||||
std::fflush(stdout);
|
||||
std::fflush(stderr);
|
||||
|
||||
g_dieHandler(rx::vformat(fmt, args), location);
|
||||
} else {
|
||||
rx::print(stderr, "\n");
|
||||
rx::print(stderr, "{}:{}:{}: ", location.file_name(), location.line(),
|
||||
location.column());
|
||||
rx::vprint_nonunicode(stderr, fmt, args);
|
||||
rx::print(stderr, "\n");
|
||||
std::fflush(stdout);
|
||||
std::fflush(stderr);
|
||||
}
|
||||
|
||||
std::fflush(stdout);
|
||||
std::fflush(stderr);
|
||||
std::abort();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue