mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 14:01:25 +12: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
4 changed files with 76 additions and 17 deletions
|
@ -313,17 +313,10 @@ void fmt_class_string<src_loc>::format(std::string& out, u64 arg)
|
||||||
|
|
||||||
namespace fmt
|
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"};
|
std::string out;
|
||||||
fmt::append(out, "%s", loc);
|
fmt::append(out, "%s%s", msg ? msg : u8"Verification failed", 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);
|
|
||||||
thread_ctrl::emergency_exit(out);
|
thread_ctrl::emergency_exit(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -293,4 +293,66 @@ namespace fmt
|
||||||
|
|
||||||
template <typename CharT, usz N, typename... Args>
|
template <typename CharT, usz N, typename... Args>
|
||||||
throw_exception(const CharT(&)[N], const Args&...) -> throw_exception<CharT, N, 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
|
#endif
|
||||||
|
|
||||||
ensure(thread_ctrl::is_main());
|
ensure(thread_ctrl::is_main(), "Not main thread");
|
||||||
|
|
||||||
// Initialize TSC freq (in case it isn't)
|
// Initialize TSC freq (in case it isn't)
|
||||||
static_cast<void>(utils::get_tsc_freq());
|
static_cast<void>(utils::get_tsc_freq());
|
||||||
|
|
|
@ -802,6 +802,12 @@ struct const_str_t<umax>
|
||||||
const char* chars2;
|
const char* chars2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const_str_t()
|
||||||
|
: size(0)
|
||||||
|
, chars(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template <usz N>
|
template <usz N>
|
||||||
constexpr const_str_t(const char8_t(&a)[N])
|
constexpr const_str_t(const char8_t(&a)[N])
|
||||||
: size(N - 1)
|
: size(N - 1)
|
||||||
|
@ -845,12 +851,11 @@ struct src_loc
|
||||||
|
|
||||||
namespace fmt
|
namespace fmt
|
||||||
{
|
{
|
||||||
[[noreturn]] void raw_verify_error(const src_loc& loc);
|
[[noreturn]] void raw_verify_error(const src_loc& loc, const char8_t* msg);
|
||||||
[[noreturn]] void raw_narrow_error(const src_loc& loc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
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 line = __builtin_LINE(),
|
||||||
u32 col = __builtin_COLUMN(),
|
u32 col = __builtin_COLUMN(),
|
||||||
const char* file = __builtin_FILE(),
|
const char* file = __builtin_FILE(),
|
||||||
|
@ -861,7 +866,7 @@ constexpr decltype(auto) ensure(T&& arg,
|
||||||
return std::forward<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
|
// narrow() function details
|
||||||
|
@ -946,8 +951,7 @@ template <typename To = void, typename From, typename = decltype(static_cast<To>
|
||||||
// Narrow check
|
// Narrow check
|
||||||
if (narrow_impl<From, To>::test(value)) [[unlikely]]
|
if (narrow_impl<From, To>::test(value)) [[unlikely]]
|
||||||
{
|
{
|
||||||
// Pack value as formatting argument
|
fmt::raw_verify_error({line, col, file, func}, u8"Narrowing error");
|
||||||
fmt::raw_narrow_error({line, col, file, func});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return static_cast<To>(value);
|
return static_cast<To>(value);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue