mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-21 18:22:33 +01:00
Implement fmt::ensure (assert-like with formatted message) + fmt::tie
Arguments should be provided via fmt::tie() due to some limitations. Allow to specify simple message (non-formatting) for plain ::ensure(). Remove redundant function for narrow error.
This commit is contained in:
parent
766cc2d42f
commit
696be6aacd
@ -313,17 +313,10 @@ void fmt_class_string<src_loc>::format(std::string& out, u64 arg)
|
||||
|
||||
namespace fmt
|
||||
{
|
||||
[[noreturn]] void raw_verify_error(const src_loc& loc)
|
||||
[[noreturn]] void raw_verify_error(const src_loc& loc, const char8_t* msg)
|
||||
{
|
||||
std::string out{"Verification failed"};
|
||||
fmt::append(out, "%s", loc);
|
||||
thread_ctrl::emergency_exit(out);
|
||||
}
|
||||
|
||||
[[noreturn]] void raw_narrow_error(const src_loc& loc)
|
||||
{
|
||||
std::string out{"Narrowing error"};
|
||||
fmt::append(out, "%s", loc);
|
||||
std::string out;
|
||||
fmt::append(out, "%s%s", msg ? msg : u8"Verification failed", loc);
|
||||
thread_ctrl::emergency_exit(out);
|
||||
}
|
||||
|
||||
|
@ -293,4 +293,66 @@ namespace fmt
|
||||
|
||||
template <typename CharT, usz N, typename... Args>
|
||||
throw_exception(const CharT(&)[N], const Args&...) -> throw_exception<CharT, N, Args...>;
|
||||
|
||||
// Helper template: pack format variables
|
||||
template <typename Arg = void, typename... Args>
|
||||
struct tie
|
||||
{
|
||||
// Universal reference
|
||||
std::add_rvalue_reference_t<Arg> arg;
|
||||
|
||||
tie<Args...> next;
|
||||
|
||||
// Store only references, unveil op is postponed
|
||||
tie(Arg&& arg, Args&&... args) noexcept
|
||||
: arg(std::forward<Arg>(arg))
|
||||
, next(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
using type = std::remove_cvref_t<Arg>;
|
||||
|
||||
// Storage for fmt_unveil (deferred initialization)
|
||||
decltype(fmt_unveil<type>::get(std::declval<Arg>())) value;
|
||||
|
||||
void init(u64 to[])
|
||||
{
|
||||
value = fmt_unveil<type>::get(arg);
|
||||
to[0] = value;
|
||||
next.init(to + 1);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct tie<void>
|
||||
{
|
||||
void init(u64 to[]) const
|
||||
{
|
||||
// Isn't really null terminated, this value has no meaning
|
||||
to[0] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
tie(Args&&... args) -> tie<Args...>;
|
||||
|
||||
// Ensure with formatting
|
||||
template <typename T, typename CharT, usz N, typename... Args>
|
||||
decltype(auto) ensure(T&& arg, const CharT(&fmt)[N], tie<Args...> args,
|
||||
u32 line = __builtin_LINE(),
|
||||
u32 col = __builtin_COLUMN(),
|
||||
const char* file = __builtin_FILE(),
|
||||
const char* func = __builtin_FUNCTION()) noexcept
|
||||
{
|
||||
if (std::forward<T>(arg)) [[likely]]
|
||||
{
|
||||
return std::forward<T>(arg);
|
||||
}
|
||||
|
||||
// Prepare u64 array
|
||||
u64 data[sizeof...(Args) + 1];
|
||||
args.init(data);
|
||||
|
||||
raw_throw_exception({line, col, file, func}, reinterpret_cast<const char*>(fmt), type_info_v<std::remove_cvref_t<Args>...>, +data);
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +419,7 @@ int main(int argc, char** argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
ensure(thread_ctrl::is_main());
|
||||
ensure(thread_ctrl::is_main(), "Not main thread");
|
||||
|
||||
// Initialize TSC freq (in case it isn't)
|
||||
static_cast<void>(utils::get_tsc_freq());
|
||||
|
@ -802,6 +802,12 @@ struct const_str_t<umax>
|
||||
const char* chars2;
|
||||
};
|
||||
|
||||
const_str_t()
|
||||
: size(0)
|
||||
, chars(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
template <usz N>
|
||||
constexpr const_str_t(const char8_t(&a)[N])
|
||||
: size(N - 1)
|
||||
@ -845,12 +851,11 @@ struct src_loc
|
||||
|
||||
namespace fmt
|
||||
{
|
||||
[[noreturn]] void raw_verify_error(const src_loc& loc);
|
||||
[[noreturn]] void raw_narrow_error(const src_loc& loc);
|
||||
[[noreturn]] void raw_verify_error(const src_loc& loc, const char8_t* msg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr decltype(auto) ensure(T&& arg,
|
||||
constexpr decltype(auto) ensure(T&& arg, const_str msg = const_str(),
|
||||
u32 line = __builtin_LINE(),
|
||||
u32 col = __builtin_COLUMN(),
|
||||
const char* file = __builtin_FILE(),
|
||||
@ -861,7 +866,7 @@ constexpr decltype(auto) ensure(T&& arg,
|
||||
return std::forward<T>(arg);
|
||||
}
|
||||
|
||||
fmt::raw_verify_error({line, col, file, func});
|
||||
fmt::raw_verify_error({line, col, file, func}, msg);
|
||||
}
|
||||
|
||||
// narrow() function details
|
||||
@ -946,8 +951,7 @@ template <typename To = void, typename From, typename = decltype(static_cast<To>
|
||||
// Narrow check
|
||||
if (narrow_impl<From, To>::test(value)) [[unlikely]]
|
||||
{
|
||||
// Pack value as formatting argument
|
||||
fmt::raw_narrow_error({line, col, file, func});
|
||||
fmt::raw_verify_error({line, col, file, func}, u8"Narrowing error");
|
||||
}
|
||||
|
||||
return static_cast<To>(value);
|
||||
|
Loading…
Reference in New Issue
Block a user