mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-15 11:18:36 +12:00
EXCEPTION macro removed
fmt::throw_exception<> implemented ::narrow improved Minor fixes
This commit is contained in:
parent
46735d6b3d
commit
a7e808b35b
198 changed files with 3025 additions and 2956 deletions
|
@ -951,12 +951,6 @@ public:
|
|||
return atomic_op(atomic_post_dec<type>{});
|
||||
}
|
||||
|
||||
template<typename T2 = T>
|
||||
auto test(const T2& rhs) const
|
||||
{
|
||||
return load().test(rhs);
|
||||
}
|
||||
|
||||
template<typename T2 = T>
|
||||
auto test_and_set(const T2& rhs)
|
||||
{
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace cfg
|
|||
{
|
||||
if (_type != type::node)
|
||||
{
|
||||
throw std::logic_error("Invalid root node");
|
||||
fmt::throw_exception<std::logic_error>("Invalid root node" HERE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ namespace cfg
|
|||
{
|
||||
if (!owner.m_nodes.emplace(name, this).second)
|
||||
{
|
||||
throw std::logic_error("Node already exists");
|
||||
fmt::throw_exception<std::logic_error>("Node already exists: %s" HERE, name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ namespace cfg
|
|||
return *static_cast<const node&>(*this).m_nodes.at(name);
|
||||
}
|
||||
|
||||
throw std::logic_error("Invalid node type");
|
||||
fmt::throw_exception<std::logic_error>("Invalid node type" HERE);
|
||||
}
|
||||
|
||||
entry_base& entry_base::operator[](const char* name) const
|
||||
|
@ -42,7 +42,17 @@ namespace cfg
|
|||
return *static_cast<const node&>(*this).m_nodes.at(name);
|
||||
}
|
||||
|
||||
throw std::logic_error("Invalid node type");
|
||||
fmt::throw_exception<std::logic_error>("Invalid node type" HERE);
|
||||
}
|
||||
|
||||
bool entry_base::from_string(const std::string&)
|
||||
{
|
||||
fmt::throw_exception<std::logic_error>("from_string() purecall" HERE);
|
||||
}
|
||||
|
||||
bool entry_base::from_list(std::vector<std::string>&&)
|
||||
{
|
||||
fmt::throw_exception<std::logic_error>("from_list() purecall" HERE);
|
||||
}
|
||||
|
||||
// Emit YAML
|
||||
|
|
|
@ -69,10 +69,7 @@ namespace cfg
|
|||
}
|
||||
|
||||
// Try to convert from string (optional)
|
||||
virtual bool from_string(const std::string&)
|
||||
{
|
||||
throw std::logic_error("from_string() not specified");
|
||||
}
|
||||
virtual bool from_string(const std::string&);
|
||||
|
||||
// Get string list (optional)
|
||||
virtual std::vector<std::string> to_list() const
|
||||
|
@ -81,10 +78,7 @@ namespace cfg
|
|||
}
|
||||
|
||||
// Set multiple values. Implementation-specific, optional.
|
||||
virtual bool from_list(std::vector<std::string>&&)
|
||||
{
|
||||
throw std::logic_error("from_list() not specified");
|
||||
}
|
||||
virtual bool from_list(std::vector<std::string>&&);
|
||||
};
|
||||
|
||||
// Config tree node which contains another nodes
|
||||
|
@ -223,7 +217,7 @@ namespace cfg
|
|||
}
|
||||
|
||||
map_entry(node& owner, const std::string& name, std::size_t def_index, init_type init)
|
||||
: map_entry(owner, name, def_index < init.size() ? (init.begin() + def_index)->first : throw std::logic_error("Invalid default value index"), init)
|
||||
: map_entry(owner, name, (init.begin() + (def_index < init.size() ? def_index : 0))->first, init)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -358,7 +352,7 @@ namespace cfg
|
|||
{
|
||||
if (value < Min || value > Max)
|
||||
{
|
||||
throw fmt::exception("Value out of the valid range: %lld" HERE, s64{ value });
|
||||
fmt::throw_exception("Value out of the valid range: %lld" HERE, s64{ value });
|
||||
}
|
||||
|
||||
m_value = value;
|
||||
|
|
|
@ -18,13 +18,13 @@ static std::unique_ptr<wchar_t[]> to_wchar(const std::string& source)
|
|||
{
|
||||
const auto buf_size = source.size() + 1; // size + null terminator
|
||||
|
||||
const int size = source.size() < INT_MAX ? static_cast<int>(buf_size) : throw fmt::exception("to_wchar(): invalid source length (0x%llx)", source.size());
|
||||
const int size = source.size() < INT_MAX ? static_cast<int>(buf_size) : (fmt::throw_exception("to_wchar(): invalid source length (0x%llx)", source.size()), 0);
|
||||
|
||||
std::unique_ptr<wchar_t[]> buffer(new wchar_t[buf_size]); // allocate buffer assuming that length is the max possible size
|
||||
|
||||
if (!MultiByteToWideChar(CP_UTF8, 0, source.c_str(), size, buffer.get(), size))
|
||||
{
|
||||
throw fmt::exception("to_wchar(): MultiByteToWideChar() failed: error %u.", GetLastError());
|
||||
fmt::throw_exception("to_wchar(): MultiByteToWideChar() failed: error %u.", GetLastError());
|
||||
}
|
||||
|
||||
return buffer;
|
||||
|
@ -34,7 +34,7 @@ static void to_utf8(std::string& result, const wchar_t* source)
|
|||
{
|
||||
const auto length = std::wcslen(source);
|
||||
|
||||
const int buf_size = length <= INT_MAX / 3 ? static_cast<int>(length) * 3 + 1 : throw fmt::exception("to_utf8(): invalid source length (0x%llx)", length);
|
||||
const int buf_size = length <= INT_MAX / 3 ? static_cast<int>(length) * 3 + 1 : (fmt::throw_exception("to_utf8(): invalid source length (0x%llx)", length), 0);
|
||||
|
||||
result.resize(buf_size); // set max possible length for utf-8 + null terminator
|
||||
|
||||
|
@ -44,7 +44,7 @@ static void to_utf8(std::string& result, const wchar_t* source)
|
|||
}
|
||||
else
|
||||
{
|
||||
throw fmt::exception("to_utf8(): WideCharToMultiByte() failed: error %u.", GetLastError());
|
||||
fmt::throw_exception("to_utf8(): WideCharToMultiByte() failed: error %u.", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ static fs::error to_error(DWORD e)
|
|||
case ERROR_NEGATIVE_SEEK: return fs::error::inval;
|
||||
case ERROR_DIRECTORY: return fs::error::inval;
|
||||
case ERROR_INVALID_NAME: return fs::error::inval;
|
||||
default: throw fmt::exception("Unknown Win32 error: %u.", e);
|
||||
default: fmt::throw_exception("Unknown Win32 error: %u.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ static fs::error to_error(int e)
|
|||
case ENOENT: return fs::error::noent;
|
||||
case EEXIST: return fs::error::exist;
|
||||
case EINVAL: return fs::error::inval;
|
||||
default: throw fmt::exception("Unknown system error: %d.", e);
|
||||
default: fmt::throw_exception("Unknown system error: %d.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -465,7 +465,7 @@ bool fs::rename(const std::string& from, const std::string& to)
|
|||
|
||||
if (device != get_virtual_device(to))
|
||||
{
|
||||
throw fmt::exception("fs::rename() between different devices not implemented.\nFrom: %s\nTo: %s", from, to);
|
||||
fmt::throw_exception("fs::rename() between different devices not implemented.\nFrom: %s\nTo: %s", from, to);
|
||||
}
|
||||
|
||||
if (device)
|
||||
|
@ -498,7 +498,7 @@ bool fs::copy_file(const std::string& from, const std::string& to, bool overwrit
|
|||
|
||||
if (device != get_virtual_device(to) || device) // TODO
|
||||
{
|
||||
throw fmt::exception("fs::copy_file() for virtual devices not implemented.\nFrom: %s\nTo: %s", from, to);
|
||||
fmt::throw_exception("fs::copy_file() for virtual devices not implemented.\nFrom: %s\nTo: %s", from, to);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -622,12 +622,12 @@ bool fs::truncate_file(const std::string& path, u64 length)
|
|||
|
||||
void fs::file::xnull() const
|
||||
{
|
||||
throw std::logic_error("fs::file is null");
|
||||
fmt::throw_exception<std::logic_error>("fs::file is null");
|
||||
}
|
||||
|
||||
void fs::file::xfail() const
|
||||
{
|
||||
throw fmt::exception("Unexpected fs::error %s", g_tls_error);
|
||||
fmt::throw_exception("Unexpected fs::error %s", g_tls_error);
|
||||
}
|
||||
|
||||
bool fs::file::open(const std::string& path, bs_t<open_mode> mode)
|
||||
|
@ -694,7 +694,7 @@ bool fs::file::open(const std::string& path, bs_t<open_mode> mode)
|
|||
FILE_BASIC_INFO basic_info;
|
||||
if (!GetFileInformationByHandleEx(m_handle, FileBasicInfo, &basic_info, sizeof(FILE_BASIC_INFO)))
|
||||
{
|
||||
throw fmt::exception("Win32 error: %u." HERE, GetLastError());
|
||||
fmt::throw_exception("Win32 error: %u." HERE, GetLastError());
|
||||
}
|
||||
|
||||
stat_t info;
|
||||
|
@ -730,7 +730,7 @@ bool fs::file::open(const std::string& path, bs_t<open_mode> mode)
|
|||
|
||||
if (!result || !SetFilePointerEx(m_handle, old, NULL, FILE_BEGIN)) // restore position
|
||||
{
|
||||
throw fmt::exception("Win32 error: %u." HERE, GetLastError());
|
||||
fmt::throw_exception("Win32 error: %u." HERE, GetLastError());
|
||||
}
|
||||
|
||||
return result != FALSE;
|
||||
|
@ -745,7 +745,7 @@ bool fs::file::open(const std::string& path, bs_t<open_mode> mode)
|
|||
DWORD nread;
|
||||
if (!ReadFile(m_handle, buffer, size, &nread, NULL))
|
||||
{
|
||||
throw fmt::exception("Win32 error: %u." HERE, GetLastError());
|
||||
fmt::throw_exception("Win32 error: %u." HERE, GetLastError());
|
||||
}
|
||||
|
||||
return nread;
|
||||
|
@ -760,7 +760,7 @@ bool fs::file::open(const std::string& path, bs_t<open_mode> mode)
|
|||
DWORD nwritten;
|
||||
if (!WriteFile(m_handle, buffer, size, &nwritten, NULL))
|
||||
{
|
||||
throw fmt::exception("Win32 error: %u." HERE, GetLastError());
|
||||
fmt::throw_exception("Win32 error: %u." HERE, GetLastError());
|
||||
}
|
||||
|
||||
return nwritten;
|
||||
|
@ -775,11 +775,11 @@ bool fs::file::open(const std::string& path, bs_t<open_mode> mode)
|
|||
whence == seek_set ? FILE_BEGIN :
|
||||
whence == seek_cur ? FILE_CURRENT :
|
||||
whence == seek_end ? FILE_END :
|
||||
throw fmt::exception("Invalid whence (0x%x)" HERE, whence);
|
||||
(fmt::throw_exception("Invalid whence (0x%x)" HERE, whence), 0);
|
||||
|
||||
if (!SetFilePointerEx(m_handle, pos, &pos, mode))
|
||||
{
|
||||
throw fmt::exception("Win32 error: %u." HERE, GetLastError());
|
||||
fmt::throw_exception("Win32 error: %u." HERE, GetLastError());
|
||||
}
|
||||
|
||||
return pos.QuadPart;
|
||||
|
@ -790,7 +790,7 @@ bool fs::file::open(const std::string& path, bs_t<open_mode> mode)
|
|||
LARGE_INTEGER size;
|
||||
if (!GetFileSizeEx(m_handle, &size))
|
||||
{
|
||||
throw fmt::exception("Win32 error: %u." HERE, GetLastError());
|
||||
fmt::throw_exception("Win32 error: %u." HERE, GetLastError());
|
||||
}
|
||||
|
||||
return size.QuadPart;
|
||||
|
@ -838,7 +838,7 @@ bool fs::file::open(const std::string& path, bs_t<open_mode> mode)
|
|||
struct ::stat file_info;
|
||||
if (::fstat(m_fd, &file_info) != 0)
|
||||
{
|
||||
throw fmt::exception("System error: %d." HERE, errno);
|
||||
fmt::throw_exception("System error: %d." HERE, errno);
|
||||
}
|
||||
|
||||
stat_t info;
|
||||
|
@ -868,7 +868,7 @@ bool fs::file::open(const std::string& path, bs_t<open_mode> mode)
|
|||
const auto result = ::read(m_fd, buffer, count);
|
||||
if (result == -1)
|
||||
{
|
||||
throw fmt::exception("System error: %d." HERE, errno);
|
||||
fmt::throw_exception("System error: %d." HERE, errno);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -879,7 +879,7 @@ bool fs::file::open(const std::string& path, bs_t<open_mode> mode)
|
|||
const auto result = ::write(m_fd, buffer, count);
|
||||
if (result == -1)
|
||||
{
|
||||
throw fmt::exception("System error: %d." HERE, errno);
|
||||
fmt::throw_exception("System error: %d." HERE, errno);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -891,12 +891,12 @@ bool fs::file::open(const std::string& path, bs_t<open_mode> mode)
|
|||
whence == seek_set ? SEEK_SET :
|
||||
whence == seek_cur ? SEEK_CUR :
|
||||
whence == seek_end ? SEEK_END :
|
||||
throw fmt::exception("Invalid whence (0x%x)" HERE, whence);
|
||||
(fmt::throw_exception("Invalid whence (0x%x)" HERE, whence), 0);
|
||||
|
||||
const auto result = ::lseek(m_fd, offset, mode);
|
||||
if (result == -1)
|
||||
{
|
||||
throw fmt::exception("System error: %d." HERE, errno);
|
||||
fmt::throw_exception("System error: %d." HERE, errno);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -907,7 +907,7 @@ bool fs::file::open(const std::string& path, bs_t<open_mode> mode)
|
|||
struct ::stat file_info;
|
||||
if (::fstat(m_fd, &file_info) != 0)
|
||||
{
|
||||
throw fmt::exception("System error: %d." HERE, errno);
|
||||
fmt::throw_exception("System error: %d." HERE, errno);
|
||||
}
|
||||
|
||||
return file_info.st_size;
|
||||
|
@ -938,26 +938,27 @@ fs::file::file(const void* ptr, std::size_t size)
|
|||
|
||||
fs::stat_t stat() override
|
||||
{
|
||||
throw std::logic_error("Not supported" HERE);
|
||||
fmt::throw_exception<std::logic_error>("Not supported" HERE);
|
||||
}
|
||||
|
||||
bool trunc(u64 length) override
|
||||
{
|
||||
throw std::logic_error("Not allowed" HERE);
|
||||
fmt::throw_exception<std::logic_error>("Not allowed" HERE);
|
||||
}
|
||||
|
||||
u64 read(void* buffer, u64 count) override
|
||||
{
|
||||
const u64 start = m_pos;
|
||||
const u64 end = seek(count, fs::seek_cur);
|
||||
const u64 read_size = end >= start ? end - start : throw std::logic_error("Stream overflow" HERE);
|
||||
if (end < start) fmt::throw_exception<std::logic_error>("Stream overflow" HERE);
|
||||
const u64 read_size = end - start;
|
||||
std::memcpy(buffer, m_ptr + start, read_size);
|
||||
return read_size;
|
||||
}
|
||||
|
||||
u64 write(const void* buffer, u64 count) override
|
||||
{
|
||||
throw std::logic_error("Not allowed" HERE);
|
||||
fmt::throw_exception<std::logic_error>("Not allowed" HERE);
|
||||
}
|
||||
|
||||
u64 seek(s64 offset, fs::seek_mode whence) override
|
||||
|
@ -966,7 +967,7 @@ fs::file::file(const void* ptr, std::size_t size)
|
|||
whence == fs::seek_set ? m_pos = std::min<u64>(offset, m_size) :
|
||||
whence == fs::seek_cur ? m_pos = std::min<u64>(offset + m_pos, m_size) :
|
||||
whence == fs::seek_end ? m_pos = std::min<u64>(offset + m_size, m_size) :
|
||||
throw fmt::exception("Invalid whence (0x%x)" HERE, whence);
|
||||
(fmt::throw_exception("Invalid whence (0x%x)" HERE, whence), 0);
|
||||
}
|
||||
|
||||
u64 size() override
|
||||
|
@ -980,7 +981,7 @@ fs::file::file(const void* ptr, std::size_t size)
|
|||
|
||||
void fs::dir::xnull() const
|
||||
{
|
||||
throw std::logic_error("fs::dir is null");
|
||||
fmt::throw_exception<std::logic_error>("fs::dir is null");
|
||||
}
|
||||
|
||||
bool fs::dir::open(const std::string& path)
|
||||
|
@ -1052,7 +1053,7 @@ bool fs::dir::open(const std::string& path)
|
|||
return false;
|
||||
}
|
||||
|
||||
throw fmt::exception("Win32 error: %u." HERE, GetLastError());
|
||||
fmt::throw_exception("Win32 error: %u." HERE, GetLastError());
|
||||
}
|
||||
|
||||
add_entry(found);
|
||||
|
@ -1104,7 +1105,7 @@ bool fs::dir::open(const std::string& path)
|
|||
struct ::stat file_info;
|
||||
if (::fstatat(::dirfd(m_dd), found->d_name, &file_info, 0) != 0)
|
||||
{
|
||||
throw fmt::exception("System error: %d." HERE, errno);
|
||||
fmt::throw_exception("System error: %d." HERE, errno);
|
||||
}
|
||||
|
||||
info.name = found->d_name;
|
||||
|
|
|
@ -80,7 +80,7 @@ struct MemoryManager final : llvm::RTDyldMemoryManager
|
|||
|
||||
[[noreturn]] static void null()
|
||||
{
|
||||
throw std::runtime_error("Null function" HERE);
|
||||
fmt::throw_exception("Null function" HERE);
|
||||
}
|
||||
|
||||
virtual u64 getSymbolAddress(const std::string& name) override
|
||||
|
@ -237,7 +237,7 @@ jit_compiler::jit_compiler(std::unique_ptr<llvm::Module>&& _module, std::unorder
|
|||
|
||||
if (!m_engine)
|
||||
{
|
||||
throw fmt::exception("LLVM: Failed to create ExecutionEngine: %s", result);
|
||||
fmt::throw_exception("LLVM: Failed to create ExecutionEngine: %s", result);
|
||||
}
|
||||
|
||||
m_engine->setProcessAllSections(true); // ???
|
||||
|
|
|
@ -112,7 +112,7 @@ logs::file_writer::file_writer(const std::string& name)
|
|||
{
|
||||
if (!m_file.open(fs::get_config_dir() + name, fs::rewrite + fs::append))
|
||||
{
|
||||
throw fmt::exception("Can't create log file %s (error %s)", name, fs::g_tls_error);
|
||||
fmt::throw_exception("Can't create log file %s (error %s)", name, fs::g_tls_error);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace logs
|
|||
{
|
||||
if (UNLIKELY(sev <= enabled))
|
||||
{
|
||||
message{this, sev}.broadcast(fmt, fmt_type_info::get<fmt_unveil_t<Args>...>(), fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...});
|
||||
message{this, sev}.broadcast(fmt, fmt::get_type_info<fmt_unveil_t<Args>...>(), fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,41 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
|
||||
template<typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
|
||||
constexpr T align(const T& value, std::uint64_t align)
|
||||
{
|
||||
return static_cast<T>((value + (align - 1)) & ~(align - 1));
|
||||
}
|
||||
|
||||
template<typename To, typename From>
|
||||
constexpr To narrow_impl(const To& result, const From& value, const char* message)
|
||||
{
|
||||
return static_cast<From>(result) != value ? throw std::runtime_error(message) : result;
|
||||
}
|
||||
|
||||
// Narrow cast (similar to gsl::narrow) with fixed message
|
||||
template<typename To, typename From>
|
||||
constexpr auto narrow(const From& value, const char* fixed_msg = "::narrow() failed") -> decltype(static_cast<To>(static_cast<From>(std::declval<To>())))
|
||||
{
|
||||
return narrow_impl(static_cast<To>(value), value, fixed_msg);
|
||||
}
|
||||
|
||||
// Return 32 bit .size() for container
|
||||
template<typename CT>
|
||||
constexpr auto size32(const CT& container, const char* fixed_msg = "::size32() failed") -> decltype(static_cast<std::uint32_t>(container.size()))
|
||||
{
|
||||
return narrow<std::uint32_t>(container.size(), fixed_msg);
|
||||
}
|
||||
|
||||
// Return 32 bit size for an array
|
||||
template<typename T, std::size_t Size>
|
||||
constexpr std::uint32_t size32(const T(&)[Size])
|
||||
{
|
||||
static_assert(Size <= UINT32_MAX, "size32() error: too big");
|
||||
return static_cast<std::uint32_t>(Size);
|
||||
}
|
||||
#include "types.h"
|
||||
|
||||
#define CHECK_SIZE(type, size) static_assert(sizeof(type) == size, "Invalid " #type " type size")
|
||||
#define CHECK_ALIGN(type, align) static_assert(alignof(type) == align, "Invalid " #type " type alignment")
|
||||
|
@ -71,12 +36,12 @@ constexpr std::uint32_t size32(const T(&)[Size])
|
|||
#define HERE "\n(in file " __FILE__ ":" STRINGIZE(__LINE__) ")"
|
||||
|
||||
// Ensure that the expression is evaluated to true. Always evaluated and allowed to have side effects (unlike assert() macro).
|
||||
#define VERIFY(expr) do { if (!(expr)) throw std::runtime_error("Verification failed: " #expr HERE); } while (0)
|
||||
#define VERIFY(expr) do { if (!(expr)) fmt::raw_error("Verification failed: " #expr HERE); } while (0)
|
||||
|
||||
// EXPECTS() and ENSURES() are intended to check function arguments and results.
|
||||
// Expressions are not guaranteed to evaluate.
|
||||
#define EXPECTS(expr) do { if (!(expr)) throw std::runtime_error("Precondition failed: " #expr HERE); } while (0)
|
||||
#define ENSURES(expr) do { if (!(expr)) throw std::runtime_error("Postcondition failed: " #expr HERE); } while (0)
|
||||
#define EXPECTS(expr) do { if (!(expr)) fmt::raw_error("Precondition failed: " #expr HERE); } while (0)
|
||||
#define ENSURES(expr) do { if (!(expr)) fmt::raw_error("Postcondition failed: " #expr HERE); } while (0)
|
||||
|
||||
#define DECLARE(...) decltype(__VA_ARGS__) __VA_ARGS__
|
||||
|
||||
|
|
|
@ -128,6 +128,52 @@ void fmt_class_string<v128>::format(std::string& out, u64 arg)
|
|||
|
||||
namespace fmt
|
||||
{
|
||||
void raw_error(const char* msg)
|
||||
{
|
||||
std::string out;
|
||||
|
||||
out += "Error: ";
|
||||
out += msg;
|
||||
|
||||
throw std::runtime_error(out);
|
||||
}
|
||||
|
||||
void raw_narrow_error(const char* msg, const fmt_type_info* sup, u64 arg)
|
||||
{
|
||||
std::string out;
|
||||
|
||||
out += "Narrow error: (";
|
||||
sup->fmt_string(out, arg); // Print value
|
||||
out += ")";
|
||||
|
||||
if (msg)
|
||||
{
|
||||
out += " ";
|
||||
out += msg;
|
||||
}
|
||||
|
||||
throw std::range_error(out);
|
||||
}
|
||||
|
||||
// Hidden template
|
||||
template<typename T>
|
||||
void raw_throw_exception(const char* fmt, const fmt_type_info* sup, const u64* args)
|
||||
{
|
||||
std::string out;
|
||||
raw_append(out, fmt, sup, args);
|
||||
throw T{out};
|
||||
}
|
||||
|
||||
// Explicit instantiations (not exhaustive)
|
||||
template void raw_throw_exception<std::runtime_error>(const char*, const fmt_type_info*, const u64*);
|
||||
template void raw_throw_exception<std::logic_error>(const char*, const fmt_type_info*, const u64*);
|
||||
template void raw_throw_exception<std::domain_error>(const char*, const fmt_type_info*, const u64*);
|
||||
template void raw_throw_exception<std::invalid_argument>(const char*, const fmt_type_info*, const u64*);
|
||||
template void raw_throw_exception<std::out_of_range>(const char*, const fmt_type_info*, const u64*);
|
||||
template void raw_throw_exception<std::range_error>(const char*, const fmt_type_info*, const u64*);
|
||||
template void raw_throw_exception<std::overflow_error>(const char*, const fmt_type_info*, const u64*);
|
||||
template void raw_throw_exception<std::underflow_error>(const char*, const fmt_type_info*, const u64*);
|
||||
|
||||
struct cfmt_src;
|
||||
}
|
||||
|
||||
|
@ -191,13 +237,6 @@ void fmt::raw_append(std::string& out, const char* fmt, const fmt_type_info* sup
|
|||
cfmt_append(out, fmt, cfmt_src{sup, args});
|
||||
}
|
||||
|
||||
char* fmt::alloc_format(const char* fmt, const fmt_type_info* sup, const u64* args) noexcept
|
||||
{
|
||||
std::string str;
|
||||
raw_append(str, fmt, sup, args);
|
||||
return static_cast<char*>(std::memcpy(std::malloc(str.size() + 1), str.data(), str.size() + 1));
|
||||
}
|
||||
|
||||
std::string fmt::replace_first(const std::string& src, const std::string& from, const std::string& to)
|
||||
{
|
||||
auto pos = src.find(from);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include "Platform.h"
|
||||
#include "types.h"
|
||||
|
@ -212,18 +211,6 @@ struct fmt_type_info
|
|||
&fmt_class_string<T>::format,
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
static inline const fmt_type_info* get()
|
||||
{
|
||||
// Constantly initialized null-terminated list of type-specific information
|
||||
static constexpr fmt_type_info result[sizeof...(Args) + 1]
|
||||
{
|
||||
make<Args>()...
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Arg>
|
||||
|
@ -235,6 +222,18 @@ using fmt_args_t = const u64(&&)[sizeof...(Args) + 1];
|
|||
|
||||
namespace fmt
|
||||
{
|
||||
template<typename... Args>
|
||||
const fmt_type_info* get_type_info()
|
||||
{
|
||||
// Constantly initialized null-terminated list of type-specific information
|
||||
static constexpr fmt_type_info result[sizeof...(Args) + 1]
|
||||
{
|
||||
fmt_type_info::make<Args>()...
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Internal formatting function
|
||||
void raw_append(std::string& out, const char*, const fmt_type_info*, const u64*) noexcept;
|
||||
|
||||
|
@ -242,7 +241,7 @@ namespace fmt
|
|||
template<typename... Args>
|
||||
static SAFE_BUFFERS void append(std::string& out, const char* fmt, const Args&... args)
|
||||
{
|
||||
raw_append(out, fmt, fmt_type_info::get<fmt_unveil_t<Args>...>(), fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...});
|
||||
raw_append(out, fmt, fmt::get_type_info<fmt_unveil_t<Args>...>(), fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...});
|
||||
}
|
||||
|
||||
// Formatting function
|
||||
|
@ -254,24 +253,14 @@ namespace fmt
|
|||
return result;
|
||||
}
|
||||
|
||||
// Internal helper function
|
||||
char* alloc_format(const char*, const fmt_type_info*, const u64*) noexcept;
|
||||
// Internal exception message formatting template, must be explicitly specialized or instantiated in cpp to minimize code bloat
|
||||
template<typename T>
|
||||
[[noreturn]] void raw_throw_exception(const char*, const fmt_type_info*, const u64*);
|
||||
|
||||
// Exception type with formatting constructor
|
||||
template<typename Base>
|
||||
class exception_t : public Base
|
||||
// Throw exception with formatting
|
||||
template<typename T = std::runtime_error, typename... Args>
|
||||
[[noreturn]] SAFE_BUFFERS FORCE_INLINE void throw_exception(const char* fmt, const Args&... args)
|
||||
{
|
||||
using base = Base;
|
||||
|
||||
public:
|
||||
template<typename... Args>
|
||||
SAFE_BUFFERS exception_t(const char* fmt, const Args&... args)
|
||||
: base((fmt = alloc_format(fmt, fmt_type_info::get<fmt_unveil_t<Args>...>(), fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...})))
|
||||
{
|
||||
std::free(const_cast<char*>(fmt));
|
||||
}
|
||||
};
|
||||
|
||||
// Exception type derived from std::runtime_error with formatting constructor
|
||||
using exception = exception_t<std::runtime_error>;
|
||||
raw_throw_exception<T>(fmt, fmt::get_type_info<fmt_unveil_t<Args>...>(), fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,14 +27,18 @@ namespace gsl
|
|||
enum class byte : u8;
|
||||
}
|
||||
|
||||
namespace fmt
|
||||
{
|
||||
}
|
||||
|
||||
// Formatting helper, type-specific preprocessing for improving safety and functionality
|
||||
template<typename T, typename = void>
|
||||
struct fmt_unveil;
|
||||
|
||||
struct fmt_type_info;
|
||||
|
||||
namespace fmt
|
||||
{
|
||||
template<typename... Args>
|
||||
const fmt_type_info* get_type_info();
|
||||
}
|
||||
|
||||
template<typename T, std::size_t Align = alignof(T), std::size_t Size = sizeof(T)>
|
||||
struct se_storage;
|
||||
|
||||
|
@ -410,6 +414,84 @@ struct ignore
|
|||
}
|
||||
};
|
||||
|
||||
template<typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
|
||||
constexpr T align(const T& value, std::uint64_t align)
|
||||
{
|
||||
return static_cast<T>((value + (align - 1)) & ~(align - 1));
|
||||
}
|
||||
|
||||
namespace fmt
|
||||
{
|
||||
[[noreturn]] void raw_error(const char* msg);
|
||||
|
||||
[[noreturn]] void raw_narrow_error(const char* msg, const fmt_type_info* sup, u64 arg);
|
||||
}
|
||||
|
||||
// Narrow cast (throws on failure)
|
||||
template<typename To = void, typename From, typename = decltype(static_cast<To>(std::declval<From>()))>
|
||||
inline To narrow(const From& value, const char* msg = nullptr)
|
||||
{
|
||||
// Allow "narrowing to void" and ensure it always fails in this case
|
||||
auto&& result = static_cast<std::conditional_t<std::is_void<To>::value, From, To>>(value);
|
||||
if (std::is_void<To>::value || static_cast<From>(result) != value)
|
||||
{
|
||||
// Pack value as formatting argument
|
||||
fmt::raw_narrow_error(msg, fmt::get_type_info<typename fmt_unveil<From>::type>(), fmt_unveil<From>::get(value));
|
||||
}
|
||||
|
||||
return static_cast<std::conditional_t<std::is_void<To>::value, void, decltype(result)>>(result);
|
||||
}
|
||||
|
||||
// Returns u32 size() for container
|
||||
template<typename CT, typename = decltype(static_cast<u32>(std::declval<CT>().size()))>
|
||||
inline u32 size32(const CT& container, const char* msg = nullptr)
|
||||
{
|
||||
return narrow<u32>(container.size(), msg);
|
||||
}
|
||||
|
||||
// Returns u32 size for an array
|
||||
template<typename T, std::size_t Size>
|
||||
constexpr u32 size32(const T(&)[Size], const char* msg = nullptr)
|
||||
{
|
||||
return static_cast<u32>(Size);
|
||||
}
|
||||
|
||||
template<typename T1, typename = std::enable_if_t<std::is_integral<T1>::value>>
|
||||
constexpr bool test(const T1& value)
|
||||
{
|
||||
return value != 0;
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename = std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value>>
|
||||
constexpr bool test(const T1& lhs, const T2& rhs)
|
||||
{
|
||||
return (lhs & rhs) != 0;
|
||||
}
|
||||
|
||||
template<typename T, typename T2, typename = std::enable_if_t<std::is_integral<T>::value && std::is_integral<T2>::value>>
|
||||
inline bool test_and_set(T& lhs, const T2& rhs)
|
||||
{
|
||||
const bool result = (lhs & rhs) != 0;
|
||||
lhs |= rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, typename T2, typename = std::enable_if_t<std::is_integral<T>::value && std::is_integral<T2>::value>>
|
||||
inline bool test_and_reset(T& lhs, const T2& rhs)
|
||||
{
|
||||
const bool result = (lhs & rhs) != 0;
|
||||
lhs &= ~rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, typename T2, typename = std::enable_if_t<std::is_integral<T>::value && std::is_integral<T2>::value>>
|
||||
inline bool test_and_complement(T& lhs, const T2& rhs)
|
||||
{
|
||||
const bool result = (lhs & rhs) != 0;
|
||||
lhs ^= rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Simplified hash algorithm for pointers. May be used in std::unordered_(map|set).
|
||||
template<typename T, std::size_t Align = alignof(T)>
|
||||
struct pointer_hash
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace utils
|
|||
case version_type::release: return "Release";
|
||||
}
|
||||
|
||||
throw type;
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
uint version::to_hex() const
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue