mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 21:41:26 +12:00
Replace src_loc with std::soource_location
This commit is contained in:
parent
2d32ba5ca2
commit
a2dcbb9c13
17 changed files with 146 additions and 290 deletions
|
@ -8,7 +8,7 @@
|
||||||
#pragma GCC diagnostic ignored "-Weffc++"
|
#pragma GCC diagnostic ignored "-Weffc++"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T, uint N>
|
template <typename T, uint N>
|
||||||
struct bf_base
|
struct bf_base
|
||||||
{
|
{
|
||||||
using type = T;
|
using type = T;
|
||||||
|
@ -35,7 +35,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Bitfield accessor (N bits from I position, 0 is LSB)
|
// Bitfield accessor (N bits from I position, 0 is LSB)
|
||||||
template<typename T, uint I, uint N>
|
template <typename T, uint I, uint N>
|
||||||
struct bf_t : bf_base<T, N>
|
struct bf_t : bf_base<T, N>
|
||||||
{
|
{
|
||||||
using type = typename bf_t::type;
|
using type = typename bf_t::type;
|
||||||
|
@ -156,8 +156,17 @@ struct bf_t : bf_base<T, N>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, uint I, uint N>
|
||||||
|
struct std::common_type<bf_t<T, I, N>, bf_t<T, I, N>> : std::common_type<T> {};
|
||||||
|
|
||||||
|
template <typename T, uint I, uint N, typename T2>
|
||||||
|
struct std::common_type<bf_t<T, I, N>, T2> : std::common_type<T2, std::common_type_t<T>> {};
|
||||||
|
|
||||||
|
template <typename T, uint I, uint N, typename T2>
|
||||||
|
struct std::common_type<T2, bf_t<T, I, N>> : std::common_type<std::common_type_t<T>, T2> {};
|
||||||
|
|
||||||
// Field pack (concatenated from left to right)
|
// Field pack (concatenated from left to right)
|
||||||
template<typename F = void, typename... Fields>
|
template <typename F = void, typename... Fields>
|
||||||
struct cf_t : bf_base<typename F::type, F::bitsize + cf_t<Fields...>::bitsize>
|
struct cf_t : bf_base<typename F::type, F::bitsize + cf_t<Fields...>::bitsize>
|
||||||
{
|
{
|
||||||
using type = typename cf_t::type;
|
using type = typename cf_t::type;
|
||||||
|
@ -198,7 +207,7 @@ struct cf_t : bf_base<typename F::type, F::bitsize + cf_t<Fields...>::bitsize>
|
||||||
};
|
};
|
||||||
|
|
||||||
// Empty field pack (recursion terminator)
|
// Empty field pack (recursion terminator)
|
||||||
template<>
|
template <>
|
||||||
struct cf_t<void>
|
struct cf_t<void>
|
||||||
{
|
{
|
||||||
static constexpr uint bitsize = 0;
|
static constexpr uint bitsize = 0;
|
||||||
|
@ -208,13 +217,13 @@ struct cf_t<void>
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
static constexpr auto extract(const T&) -> decltype(+T())
|
static constexpr auto extract(const T&) -> decltype(+T())
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
static constexpr T insert(T /*value*/)
|
static constexpr T insert(T /*value*/)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -222,7 +231,7 @@ struct cf_t<void>
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fixed field (provides constant values in field pack)
|
// Fixed field (provides constant values in field pack)
|
||||||
template<typename T, T V, uint N>
|
template <typename T, T V, uint N>
|
||||||
struct ff_t : bf_base<T, N>
|
struct ff_t : bf_base<T, N>
|
||||||
{
|
{
|
||||||
using type = typename ff_t::type;
|
using type = typename ff_t::type;
|
||||||
|
@ -246,7 +255,7 @@ struct ff_t : bf_base<T, N>
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T, uint I, uint N>
|
template <typename T, uint I, uint N>
|
||||||
struct fmt_unveil<bf_t<T, I, N>, void>
|
struct fmt_unveil<bf_t<T, I, N>, void>
|
||||||
{
|
{
|
||||||
using type = typename fmt_unveil<std::common_type_t<T>>::type;
|
using type = typename fmt_unveil<std::common_type_t<T>>::type;
|
||||||
|
@ -257,7 +266,7 @@ struct fmt_unveil<bf_t<T, I, N>, void>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename F, typename... Fields>
|
template <typename F, typename... Fields>
|
||||||
struct fmt_unveil<cf_t<F, Fields...>, void>
|
struct fmt_unveil<cf_t<F, Fields...>, void>
|
||||||
{
|
{
|
||||||
using type = typename fmt_unveil<std::common_type_t<typename F::type>>::type;
|
using type = typename fmt_unveil<std::common_type_t<typename F::type>>::type;
|
||||||
|
@ -268,7 +277,7 @@ struct fmt_unveil<cf_t<F, Fields...>, void>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, T V, uint N>
|
template <typename T, T V, uint N>
|
||||||
struct fmt_unveil<ff_t<T, V, N>, void>
|
struct fmt_unveil<ff_t<T, V, N>, void>
|
||||||
{
|
{
|
||||||
using type = typename fmt_unveil<std::common_type_t<T>>::type;
|
using type = typename fmt_unveil<std::common_type_t<T>>::type;
|
||||||
|
|
|
@ -1163,12 +1163,12 @@ void fs::sync()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] void fs::xnull(const src_loc& loc)
|
[[noreturn]] void fs::xnull(std::source_location loc)
|
||||||
{
|
{
|
||||||
fmt::throw_exception("Null object.%s", loc);
|
fmt::throw_exception("Null object.%s", loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] void fs::xfail(const src_loc& loc)
|
[[noreturn]] void fs::xfail(std::source_location loc)
|
||||||
{
|
{
|
||||||
fmt::throw_exception("Unexpected fs::error %s%s", g_tls_error, loc);
|
fmt::throw_exception("Unexpected fs::error %s%s", g_tls_error, loc);
|
||||||
}
|
}
|
||||||
|
|
180
Utilities/File.h
180
Utilities/File.h
|
@ -166,8 +166,8 @@ namespace fs
|
||||||
virtual std::unique_ptr<dir_base> open_dir(const std::string& path) = 0;
|
virtual std::unique_ptr<dir_base> open_dir(const std::string& path) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[noreturn]] void xnull(const src_loc&);
|
[[noreturn]] void xnull(std::source_location);
|
||||||
[[noreturn]] void xfail(const src_loc&);
|
[[noreturn]] void xfail(std::source_location);
|
||||||
[[noreturn]] void xovfl();
|
[[noreturn]] void xovfl();
|
||||||
|
|
||||||
constexpr struct pod_tag_t{} pod_tag;
|
constexpr struct pod_tag_t{} pod_tag;
|
||||||
|
@ -281,35 +281,23 @@ namespace fs
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change file size (possibly appending zero bytes)
|
// Change file size (possibly appending zero bytes)
|
||||||
bool trunc(u64 length,
|
bool trunc(u64 length, std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
if (!m_file) xnull({line, col, file, func});
|
if (!m_file) xnull(src_loc);
|
||||||
return m_file->trunc(length);
|
return m_file->trunc(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get file information
|
// Get file information
|
||||||
stat_t get_stat(
|
stat_t get_stat(std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
if (!m_file) xnull({line, col, file, func});
|
if (!m_file) xnull(src_loc);
|
||||||
return m_file->get_stat();
|
return m_file->get_stat();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync file buffers
|
// Sync file buffers
|
||||||
void sync(
|
void sync(std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
if (!m_file) xnull({line, col, file, func});
|
if (!m_file) xnull(src_loc);
|
||||||
return m_file->sync();
|
return m_file->sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,117 +305,76 @@ namespace fs
|
||||||
bool strict_read_check(u64 offset, u64 size, u64 type_size) const;
|
bool strict_read_check(u64 offset, u64 size, u64 type_size) const;
|
||||||
|
|
||||||
// Read the data from the file and return the amount of data written in buffer
|
// Read the data from the file and return the amount of data written in buffer
|
||||||
u64 read(void* buffer, u64 count,
|
u64 read(void* buffer, u64 count, std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
if (!m_file) xnull({line, col, file, func});
|
if (!m_file) xnull(src_loc);
|
||||||
return m_file->read(buffer, count);
|
return m_file->read(buffer, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the data from the file at specified offset in thread-safe manner
|
// Read the data from the file at specified offset in thread-safe manner
|
||||||
u64 read_at(u64 offset, void* buffer, u64 count,
|
u64 read_at(u64 offset, void* buffer, u64 count, std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
if (!m_file) xnull({line, col, file, func});
|
if (!m_file) xnull(src_loc);
|
||||||
return m_file->read_at(offset, buffer, count);
|
return m_file->read_at(offset, buffer, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the data to the file and return the amount of data actually written
|
// Write the data to the file and return the amount of data actually written
|
||||||
u64 write(const void* buffer, u64 count,
|
u64 write(const void* buffer, u64 count, std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
if (!m_file) xnull({line, col, file, func});
|
if (!m_file) xnull(src_loc);
|
||||||
return m_file->write(buffer, count);
|
return m_file->write(buffer, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change current position, returns resulting position
|
// Change current position, returns resulting position
|
||||||
u64 seek(s64 offset, seek_mode whence = seek_set,
|
u64 seek(s64 offset, seek_mode whence = seek_set, std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
if (!m_file) xnull({line, col, file, func});
|
if (!m_file) xnull(src_loc);
|
||||||
return m_file->seek(offset, whence);
|
return m_file->seek(offset, whence);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get file size
|
// Get file size
|
||||||
u64 size(
|
u64 size(std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
if (!m_file) xnull({line, col, file, func});
|
if (!m_file) xnull(src_loc);
|
||||||
return m_file->size();
|
return m_file->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get current position
|
// Get current position
|
||||||
u64 pos(
|
u64 pos(std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
if (!m_file) xnull({line, col, file, func});
|
if (!m_file) xnull(src_loc);
|
||||||
return m_file->seek(0, seek_cur);
|
return m_file->seek(0, seek_cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write std::basic_string unconditionally
|
// Write std::basic_string unconditionally
|
||||||
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
||||||
const file& write(const std::basic_string<T>& str,
|
const file& write(const std::basic_string<T>& str, std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
if (write(str.data(), str.size() * sizeof(T), line, col, file, func) != str.size() * sizeof(T)) xfail({line, col, file, func});
|
if (write(str.data(), str.size() * sizeof(T), src_loc) != str.size() * sizeof(T)) xfail(src_loc);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write POD unconditionally
|
// Write POD unconditionally
|
||||||
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
||||||
const file& write(const T& data,
|
const file& write(const T& data, std::source_location src_loc = std::source_location::current()) const
|
||||||
pod_tag_t = pod_tag,
|
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
if (write(std::addressof(data), sizeof(T), line, col, file, func) != sizeof(T)) xfail({line, col, file, func});
|
if (write(std::addressof(data), sizeof(T), src_loc) != sizeof(T)) xfail(src_loc);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write POD std::vector unconditionally
|
// Write POD std::vector unconditionally
|
||||||
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
||||||
const file& write(const std::vector<T>& vec,
|
const file& write(const std::vector<T>& vec, std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
if (write(vec.data(), vec.size() * sizeof(T), line, col, file, func) != vec.size() * sizeof(T)) xfail({line, col, file, func});
|
if (write(vec.data(), vec.size() * sizeof(T), src_loc) != vec.size() * sizeof(T)) xfail(src_loc);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read std::basic_string
|
// Read std::basic_string
|
||||||
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
||||||
bool read(std::basic_string<T>& str, usz _size = umax,
|
bool read(std::basic_string<T>& str, usz _size = umax, std::source_location src_loc = std::source_location::current()) const
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION(),
|
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN()) const
|
|
||||||
{
|
{
|
||||||
if (!m_file) xnull({line, col, file, func});
|
if (!m_file) xnull(src_loc);
|
||||||
|
|
||||||
if (_size != umax)
|
if (_size != umax)
|
||||||
{
|
{
|
||||||
|
@ -440,30 +387,22 @@ namespace fs
|
||||||
str.resize(_size);
|
str.resize(_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return read(str.data(), sizeof(T) * str.size(), line, col, file, func) == sizeof(T) * str.size();
|
return read(str.data(), sizeof(T) * str.size(), src_loc) == sizeof(T) * str.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read POD, sizeof(T) is used
|
// Read POD, sizeof(T) is used
|
||||||
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
||||||
bool read(T& data,
|
bool read(T& data,
|
||||||
pod_tag_t = pod_tag,
|
pod_tag_t = pod_tag, std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
return read(std::addressof(data), sizeof(T), line, col, file, func) == sizeof(T);
|
return read(std::addressof(data), sizeof(T), src_loc) == sizeof(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read POD std::vector
|
// Read POD std::vector
|
||||||
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
||||||
bool read(std::vector<T>& vec, usz _size = umax, bool use_offs = false, usz offset = umax,
|
bool read(std::vector<T>& vec, usz _size = umax, bool use_offs = false, usz offset = umax, std::source_location src_loc = std::source_location::current()) const
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION(),
|
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN()) const
|
|
||||||
{
|
{
|
||||||
if (!m_file) xnull({line, col, file, func});
|
if (!m_file) xnull(src_loc);
|
||||||
|
|
||||||
if (_size != umax)
|
if (_size != umax)
|
||||||
{
|
{
|
||||||
|
@ -478,52 +417,39 @@ namespace fs
|
||||||
|
|
||||||
if (use_offs)
|
if (use_offs)
|
||||||
{
|
{
|
||||||
return read_at(offset, vec.data(), sizeof(T) * vec.size(), line, col, file, func) == sizeof(T) * vec.size();
|
return read_at(offset, vec.data(), sizeof(T) * vec.size(), src_loc) == sizeof(T) * vec.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
return read(vec.data(), sizeof(T) * vec.size(), line, col, file, func) == sizeof(T) * vec.size();
|
return read(vec.data(), sizeof(T) * vec.size(), src_loc) == sizeof(T) * vec.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read POD (experimental)
|
// Read POD (experimental)
|
||||||
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
template <typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
||||||
T read(
|
T read(pod_tag_t = pod_tag, std::source_location src_loc = std::source_location::current()) const
|
||||||
pod_tag_t = pod_tag,
|
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
T result;
|
T result;
|
||||||
if (!read(result, pod_tag, line, col, file, func)) xfail({line, col, file, func});
|
if (!read(result, pod_tag, src_loc)) xfail(src_loc);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read full file to std::basic_string
|
// Read full file to std::basic_string
|
||||||
template <typename T = char>
|
template <typename T = char>
|
||||||
std::basic_string<T> to_string(
|
std::basic_string<T> to_string(std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
std::basic_string<T> result;
|
std::basic_string<T> result;
|
||||||
result.resize(size() / sizeof(T));
|
result.resize(size() / sizeof(T));
|
||||||
seek(0);
|
seek(0);
|
||||||
if (!read(result, result.size(), file, func, line, col)) xfail({line, col, file, func});
|
if (!read(result, result.size(), src_loc)) xfail(src_loc);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read full file to std::vector
|
// Read full file to std::vector
|
||||||
template<typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
template<typename T> requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
|
||||||
std::vector<T> to_vector(
|
std::vector<T> to_vector(std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
std::vector<T> result;
|
std::vector<T> result;
|
||||||
result.resize(size() / sizeof(T));
|
result.resize(size() / sizeof(T));
|
||||||
if (!read(result, result.size(), true, 0, file, func, line, col)) xfail({line, col, file, func});
|
if (!read(result, result.size(), true, 0, src_loc)) xfail(src_loc);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,13 +460,9 @@ namespace fs
|
||||||
file_id get_id() const;
|
file_id get_id() const;
|
||||||
|
|
||||||
// Gathered write
|
// Gathered write
|
||||||
u64 write_gather(const iovec_clone* buffers, u64 buf_count,
|
u64 write_gather(const iovec_clone* buffers, u64 buf_count, std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
if (!m_file) xnull({line, col, file, func});
|
if (!m_file) xnull(src_loc);
|
||||||
return m_file->write_gather(buffers, buf_count);
|
return m_file->write_gather(buffers, buf_count);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -584,24 +506,16 @@ namespace fs
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get next directory entry
|
// Get next directory entry
|
||||||
bool read(dir_entry& out,
|
bool read(dir_entry& out, std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
if (!m_dir) xnull({line, col, file, func});
|
if (!m_dir) xnull(src_loc);
|
||||||
return m_dir->read(out);
|
return m_dir->read(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset to the beginning
|
// Reset to the beginning
|
||||||
void rewind(
|
void rewind(std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
if (!m_dir) xnull({line, col, file, func});
|
if (!m_dir) xnull(src_loc);
|
||||||
return m_dir->rewind();
|
return m_dir->rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -414,22 +414,35 @@ void fmt_class_string<s128>::format(std::string& out, u64 arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void fmt_class_string<src_loc>::format(std::string& out, u64 arg)
|
void fmt_class_string<std::source_location>::format(std::string& out, u64 arg)
|
||||||
{
|
{
|
||||||
const src_loc& loc = get_object(arg);
|
const std::source_location& loc = get_object(arg);
|
||||||
|
|
||||||
if (loc.col != umax)
|
auto is_valid = [](auto num)
|
||||||
{
|
{
|
||||||
fmt::append(out, "\n(in file %s:%u[:%u]", loc.file, loc.line, loc.col);
|
return num && num != umax;
|
||||||
|
};
|
||||||
|
|
||||||
|
const bool has_line = is_valid(loc.line());
|
||||||
|
|
||||||
|
if (has_line && is_valid(loc.column()))
|
||||||
|
{
|
||||||
|
fmt::append(out, "\n(in file %s:%u[:%u]", loc.file_name(), loc.line(), loc.column());
|
||||||
}
|
}
|
||||||
|
else if (has_line)
|
||||||
|
{
|
||||||
|
fmt::append(out, "\n(in file %s:%u", loc.file_name(), loc.line());
|
||||||
|
}
|
||||||
|
// Let's not care about such useless corner cases
|
||||||
|
// else if (is_valid(loc.column())
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fmt::append(out, "\n(in file %s:%u", loc.file, loc.line);
|
fmt::append(out, "\n(in file %s", loc.file_name());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loc.func && *loc.func)
|
if (auto func = loc.function_name(); func && func[0])
|
||||||
{
|
{
|
||||||
fmt::append(out, ", in function %s)", loc.func);
|
fmt::append(out, ", in function %s)", func);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -452,14 +465,14 @@ 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, const char8_t* msg)
|
[[noreturn]] void raw_verify_error(std::source_location loc, const char8_t* msg)
|
||||||
{
|
{
|
||||||
std::string out;
|
std::string out;
|
||||||
fmt::append(out, "%s%s", msg ? msg : u8"Verification failed", loc);
|
fmt::append(out, "%s%s", msg ? msg : u8"Verification failed", loc);
|
||||||
thread_ctrl::emergency_exit(out);
|
thread_ctrl::emergency_exit(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] void raw_throw_exception(const src_loc& loc, const char* fmt, const fmt_type_info* sup, const u64* args)
|
[[noreturn]] void raw_throw_exception(std::source_location loc, const char* fmt, const fmt_type_info* sup, const u64* args)
|
||||||
{
|
{
|
||||||
std::string out;
|
std::string out;
|
||||||
raw_append(out, fmt, sup, args);
|
raw_append(out, fmt, sup, args);
|
||||||
|
|
|
@ -357,7 +357,7 @@ namespace fmt
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal exception message formatting template, must be explicitly specialized or instantiated in cpp to minimize code bloat
|
// Internal exception message formatting template, must be explicitly specialized or instantiated in cpp to minimize code bloat
|
||||||
[[noreturn]] void raw_throw_exception(const src_loc&, const char*, const fmt_type_info*, const u64*);
|
[[noreturn]] void raw_throw_exception(std::source_location, const char*, const fmt_type_info*, const u64*);
|
||||||
|
|
||||||
// Throw exception with formatting
|
// Throw exception with formatting
|
||||||
template <typename CharT, usz N, typename... Args>
|
template <typename CharT, usz N, typename... Args>
|
||||||
|
@ -366,13 +366,9 @@ namespace fmt
|
||||||
struct args_break_t {};
|
struct args_break_t {};
|
||||||
|
|
||||||
[[noreturn]] FORCE_INLINE SAFE_BUFFERS() throw_exception(const CharT(&fmt)[N], const Args&... args,
|
[[noreturn]] FORCE_INLINE SAFE_BUFFERS() throw_exception(const CharT(&fmt)[N], const Args&... args,
|
||||||
args_break_t = args_break_t{},
|
args_break_t = args_break_t{}, std::source_location src_loc = std::source_location::current())
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION())
|
|
||||||
{
|
{
|
||||||
raw_throw_exception({line, col, file, func}, reinterpret_cast<const char*>(fmt), type_info_v<Args...>, fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...});
|
raw_throw_exception(src_loc, reinterpret_cast<const char*>(fmt), type_info_v<Args...>, fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...});
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
|
@ -427,11 +423,7 @@ namespace fmt
|
||||||
|
|
||||||
// Ensure with formatting
|
// Ensure with formatting
|
||||||
template <typename T, typename CharT, usz N, typename... Args>
|
template <typename T, typename CharT, usz N, typename... Args>
|
||||||
decltype(auto) ensure(T&& arg, const CharT(&fmt)[N], tie<Args...> args,
|
decltype(auto) ensure(T&& arg, const CharT(&fmt)[N], tie<Args...> args, std::source_location src_loc = std::source_location::current()) noexcept
|
||||||
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]]
|
if (std::forward<T>(arg)) [[likely]]
|
||||||
{
|
{
|
||||||
|
@ -442,6 +434,6 @@ namespace fmt
|
||||||
u64 data[sizeof...(Args) + 1];
|
u64 data[sizeof...(Args) + 1];
|
||||||
args.init(data);
|
args.init(data);
|
||||||
|
|
||||||
raw_throw_exception({line, col, file, func}, reinterpret_cast<const char*>(fmt), type_info_v<std::remove_cvref_t<Args>...>, +data);
|
raw_throw_exception(src_loc, reinterpret_cast<const char*>(fmt), type_info_v<std::remove_cvref_t<Args>...>, +data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,11 +151,7 @@ struct ppu_module
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
to_be_t<T>& get_ref(u32 addr,
|
to_be_t<T>& get_ref(u32 addr, std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
constexpr usz size_element = std::is_void_v<T> ? 0 : sizeof(std::conditional_t<std::is_void_v<T>, char, T>);
|
constexpr usz size_element = std::is_void_v<T> ? 0 : sizeof(std::conditional_t<std::is_void_v<T>, char, T>);
|
||||||
if (auto ptr = get_ptr<T>(addr, u32{size_element}))
|
if (auto ptr = get_ptr<T>(addr, u32{size_element}))
|
||||||
|
@ -163,16 +159,12 @@ struct ppu_module
|
||||||
return *ptr;
|
return *ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", addr, src_loc{line, col, file, func});
|
fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", addr, src_loc);
|
||||||
return *std::add_pointer_t<to_be_t<T>>{};
|
return *std::add_pointer_t<to_be_t<T>>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename U> requires requires (const U& obj) { obj.get_ptr(); }
|
template <typename T, typename U> requires requires (const U& obj) { obj.get_ptr(); }
|
||||||
to_be_t<T>& get_ref(U&& addr, u32 index = 0,
|
to_be_t<T>& get_ref(U&& addr, u32 index = 0, std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
constexpr usz size_element = std::is_void_v<T> ? 0 : sizeof(std::conditional_t<std::is_void_v<T>, char, T>);
|
constexpr usz size_element = std::is_void_v<T> ? 0 : sizeof(std::conditional_t<std::is_void_v<T>, char, T>);
|
||||||
if (auto ptr = get_ptr<T>((addr + index).addr(), u32{size_element}))
|
if (auto ptr = get_ptr<T>((addr + index).addr(), u32{size_element}))
|
||||||
|
@ -180,7 +172,7 @@ struct ppu_module
|
||||||
return *ptr;
|
return *ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", (addr + index).addr(), src_loc{line, col, file, func});
|
fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", (addr + index).addr(), src_loc);
|
||||||
return *std::add_pointer_t<to_be_t<T>>{};
|
return *std::add_pointer_t<to_be_t<T>>{};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -6589,7 +6589,7 @@ spu_thread::spu_prio_t spu_thread::priority_t::load() const
|
||||||
if (_this->get_type() != spu_type::threaded || !_this->group->has_scheduler_context)
|
if (_this->get_type() != spu_type::threaded || !_this->group->has_scheduler_context)
|
||||||
{
|
{
|
||||||
spu_thread::spu_prio_t prio{};
|
spu_thread::spu_prio_t prio{};
|
||||||
prio.prio = smax;
|
prio.prio = s32{smax};
|
||||||
return prio;
|
return prio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,13 +220,9 @@ namespace vm
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> requires (std::is_integral_v<decltype(+T{})> && (sizeof(+T{}) > 4 || std::is_signed_v<decltype(+T{})>))
|
template<typename T> requires (std::is_integral_v<decltype(+T{})> && (sizeof(+T{}) > 4 || std::is_signed_v<decltype(+T{})>))
|
||||||
vm::addr_t cast(const T& addr,
|
vm::addr_t cast(const T& addr, std::source_location src_loc = std::source_location::current())
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION())
|
|
||||||
{
|
{
|
||||||
return vm::addr_t{::narrow<u32>(+addr, line, col, file, func)};
|
return vm::addr_t{::narrow<u32>(+addr, src_loc)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> requires (std::is_integral_v<decltype(+T{})> && (sizeof(+T{}) <= 4 && !std::is_signed_v<decltype(+T{})>))
|
template<typename T> requires (std::is_integral_v<decltype(+T{})> && (sizeof(+T{}) <= 4 && !std::is_signed_v<decltype(+T{})>))
|
||||||
|
|
|
@ -132,7 +132,7 @@ namespace rsx
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 get_address(u32 offset, u32 location, u32 size_to_check, u32 line, u32 col, const char* file, const char* func)
|
u32 get_address(u32 offset, u32 location, u32 size_to_check, std::source_location src_loc)
|
||||||
{
|
{
|
||||||
const auto render = get_current_renderer();
|
const auto render = get_current_renderer();
|
||||||
std::string_view msg;
|
std::string_view msg;
|
||||||
|
@ -249,11 +249,11 @@ namespace rsx
|
||||||
{
|
{
|
||||||
// Allow failure if specified size
|
// Allow failure if specified size
|
||||||
// This is to allow accurate recovery for failures
|
// This is to allow accurate recovery for failures
|
||||||
rsx_log.warning("rsx::get_address(offset=0x%x, location=0x%x, size=0x%x): %s%s", offset, location, size_to_check, msg, src_loc{line, col, file, func});
|
rsx_log.warning("rsx::get_address(offset=0x%x, location=0x%x, size=0x%x): %s%s", offset, location, size_to_check, msg, src_loc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::throw_exception("rsx::get_address(offset=0x%x, location=0x%x): %s%s", offset, location, msg, src_loc{line, col, file, func});
|
fmt::throw_exception("rsx::get_address(offset=0x%x, location=0x%x): %s%s", offset, location, msg, src_loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void set_rsx_yield_flag() noexcept
|
extern void set_rsx_yield_flag() noexcept
|
||||||
|
@ -3276,7 +3276,7 @@ namespace rsx
|
||||||
return pair;
|
return pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread::recover_fifo(u32 line, u32 col, const char* file, const char* func)
|
void thread::recover_fifo(std::source_location src_loc)
|
||||||
{
|
{
|
||||||
bool kill_itself = g_cfg.core.rsx_fifo_accuracy == rsx_fifo_mode::as_ps3;
|
bool kill_itself = g_cfg.core.rsx_fifo_accuracy == rsx_fifo_mode::as_ps3;
|
||||||
|
|
||||||
|
@ -3301,7 +3301,7 @@ namespace rsx
|
||||||
if (kill_itself)
|
if (kill_itself)
|
||||||
{
|
{
|
||||||
fmt::throw_exception("Dead FIFO commands queue state has been detected!"
|
fmt::throw_exception("Dead FIFO commands queue state has been detected!"
|
||||||
"\nTry increasing \"Driver Wake-Up Delay\" setting or setting \"RSX FIFO Accuracy\" to \"%s\", both in Advanced settings. Called from %s", std::min<rsx_fifo_mode>(rsx_fifo_mode{static_cast<u32>(g_cfg.core.rsx_fifo_accuracy.get()) + 1}, rsx_fifo_mode::atomic_ordered), src_loc{line, col, file, func});
|
"\nTry increasing \"Driver Wake-Up Delay\" setting or setting \"RSX FIFO Accuracy\" to \"%s\", both in Advanced settings. Called from %s", std::min<rsx_fifo_mode>(rsx_fifo_mode{static_cast<u32>(g_cfg.core.rsx_fifo_accuracy.get()) + 1}, rsx_fifo_mode::atomic_ordered), src_loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error. Should reset the queue
|
// Error. Should reset the queue
|
||||||
|
|
|
@ -123,11 +123,7 @@ namespace rsx
|
||||||
|
|
||||||
u32 get_vertex_type_size_on_host(vertex_base_type type, u32 size);
|
u32 get_vertex_type_size_on_host(vertex_base_type type, u32 size);
|
||||||
|
|
||||||
u32 get_address(u32 offset, u32 location, u32 size_to_check = 0,
|
u32 get_address(u32 offset, u32 location, u32 size_to_check = 0, std::source_location src_loc = std::source_location::current());
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION());
|
|
||||||
|
|
||||||
struct backend_configuration
|
struct backend_configuration
|
||||||
{
|
{
|
||||||
|
@ -226,10 +222,7 @@ namespace rsx
|
||||||
// Returns [count of found commands, PC of their start]
|
// Returns [count of found commands, PC of their start]
|
||||||
std::pair<u32, u32> try_get_pc_of_x_cmds_backwards(s32 count, u32 get) const;
|
std::pair<u32, u32> try_get_pc_of_x_cmds_backwards(s32 count, u32 get) const;
|
||||||
|
|
||||||
void recover_fifo(u32 line = __builtin_LINE(),
|
void recover_fifo(std::source_location src_loc = std::source_location::current());
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION());
|
|
||||||
|
|
||||||
static void fifo_wake_delay(u64 div = 1);
|
static void fifo_wake_delay(u64 div = 1);
|
||||||
u32 get_fifo_cmd() const;
|
u32 get_fifo_cmd() const;
|
||||||
|
|
|
@ -9,11 +9,7 @@ namespace vk
|
||||||
{
|
{
|
||||||
extern void print_debug_markers();
|
extern void print_debug_markers();
|
||||||
|
|
||||||
void die_with_error(VkResult error_code, std::string message,
|
void die_with_error(VkResult error_code, std::string message, std::source_location src_loc)
|
||||||
const char* file,
|
|
||||||
const char* func,
|
|
||||||
u32 line,
|
|
||||||
u32 col)
|
|
||||||
{
|
{
|
||||||
std::string error_message;
|
std::string error_message;
|
||||||
int severity = 0; // 0 - die, 1 - warn, 2 - nothing
|
int severity = 0; // 0 - die, 1 - warn, 2 - nothing
|
||||||
|
@ -100,7 +96,7 @@ namespace vk
|
||||||
error_message = "Descriptor pool creation failed (VK_ERROR_FRAGMENTATION)";
|
error_message = "Descriptor pool creation failed (VK_ERROR_FRAGMENTATION)";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error_message = fmt::format("Unknown Code (%Xh, %d)%s", static_cast<s32>(error_code), static_cast<s32>(error_code), src_loc{line, col, file, func});
|
error_message = fmt::format("Unknown Code (%Xh, %d)%s", static_cast<s32>(error_code), static_cast<s32>(error_code), src_loc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,9 +107,9 @@ namespace vk
|
||||||
print_debug_markers();
|
print_debug_markers();
|
||||||
|
|
||||||
if (!message.empty()) message += "\n\n";
|
if (!message.empty()) message += "\n\n";
|
||||||
fmt::throw_exception("%sAssertion Failed! Vulkan API call failed with unrecoverable error: %s%s", message, error_message, src_loc{line, col, file, func});
|
fmt::throw_exception("%sAssertion Failed! Vulkan API call failed with unrecoverable error: %s%s", message, error_message, src_loc);
|
||||||
case 1:
|
case 1:
|
||||||
rsx_log.error("Vulkan API call has failed with an error but will continue: %s%s", error_message, src_loc{line, col, file, func});
|
rsx_log.error("Vulkan API call has failed with an error but will continue: %s%s", error_message, src_loc);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -8,11 +8,7 @@ namespace vk
|
||||||
#define CHECK_RESULT(expr) { VkResult _res = (expr); if (_res != VK_SUCCESS) vk::die_with_error(_res); }
|
#define CHECK_RESULT(expr) { VkResult _res = (expr); if (_res != VK_SUCCESS) vk::die_with_error(_res); }
|
||||||
#define CHECK_RESULT_EX(expr, msg) { VkResult _res = (expr); if (_res != VK_SUCCESS) vk::die_with_error(_res, msg); }
|
#define CHECK_RESULT_EX(expr, msg) { VkResult _res = (expr); if (_res != VK_SUCCESS) vk::die_with_error(_res, msg); }
|
||||||
|
|
||||||
void die_with_error(VkResult error_code, std::string message = {},
|
void die_with_error(VkResult error_code, std::string message = {}, std::source_location src_loc = std::source_location::current());
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION(),
|
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN());
|
|
||||||
|
|
||||||
VKAPI_ATTR VkBool32 VKAPI_CALL dbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
|
VKAPI_ATTR VkBool32 VKAPI_CALL dbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
|
||||||
u64 srcObject, usz location, s32 msgCode,
|
u64 srcObject, usz location, s32 msgCode,
|
||||||
|
|
|
@ -162,9 +162,9 @@ void fmt_class_string<cfg_mode>::format(std::string& out, u64 arg)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Emulator::CallFromMainThread(std::function<void()>&& func, atomic_t<u32>* wake_up, bool track_emu_state, u64 stop_ctr, u32 line, u32 col, const char* file, const char* fun) const
|
void Emulator::CallFromMainThread(std::function<void()>&& func, atomic_t<u32>* wake_up, bool track_emu_state, u64 stop_ctr, std::source_location src_loc) const
|
||||||
{
|
{
|
||||||
std::function<void()> final_func = [this, before = IsStopped(), track_emu_state, thread_name = thread_ctrl::get_name(), src = src_loc{line, col, file, fun}
|
std::function<void()> final_func = [this, before = IsStopped(), track_emu_state, thread_name = thread_ctrl::get_name(), src = src_loc
|
||||||
, count = (stop_ctr == umax ? +m_stop_ctr : stop_ctr), func = std::move(func)]
|
, count = (stop_ctr == umax ? +m_stop_ctr : stop_ctr), func = std::move(func)]
|
||||||
{
|
{
|
||||||
const bool call_it = (!track_emu_state || (count == m_stop_ctr && before == IsStopped()));
|
const bool call_it = (!track_emu_state || (count == m_stop_ctr && before == IsStopped()));
|
||||||
|
@ -180,19 +180,19 @@ void Emulator::CallFromMainThread(std::function<void()>&& func, atomic_t<u32>* w
|
||||||
m_cb.call_from_main_thread(std::move(final_func), wake_up);
|
m_cb.call_from_main_thread(std::move(final_func), wake_up);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Emulator::BlockingCallFromMainThread(std::function<void()>&& func, u32 line, u32 col, const char* file, const char* fun) const
|
void Emulator::BlockingCallFromMainThread(std::function<void()>&& func, std::source_location src_loc) const
|
||||||
{
|
{
|
||||||
atomic_t<u32> wake_up = 0;
|
atomic_t<u32> wake_up = 0;
|
||||||
|
|
||||||
sys_log.trace("Blocking Callback from thread '%s' at [%s] is queued", thread_ctrl::get_name(), src_loc{line, col, file, fun});
|
sys_log.trace("Blocking Callback from thread '%s' at [%s] is queued", thread_ctrl::get_name(), src_loc);
|
||||||
|
|
||||||
CallFromMainThread(std::move(func), &wake_up, true, umax, line, col, file, fun);
|
CallFromMainThread(std::move(func), &wake_up, true, umax, src_loc);
|
||||||
|
|
||||||
while (!wake_up)
|
while (!wake_up)
|
||||||
{
|
{
|
||||||
if (!thread_ctrl::get_current())
|
if (!thread_ctrl::get_current())
|
||||||
{
|
{
|
||||||
fmt::throw_exception("Calling thread of BlockingCallFromMainThread is not of named_thread<>, calling from %s", src_loc{line, col, file, fun});
|
fmt::throw_exception("Calling thread of BlockingCallFromMainThread is not of named_thread<>, calling from %s", src_loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
wake_up.wait(0);
|
wake_up.wait(0);
|
||||||
|
|
|
@ -191,17 +191,10 @@ public:
|
||||||
|
|
||||||
// Call from the GUI thread
|
// Call from the GUI thread
|
||||||
void CallFromMainThread(std::function<void()>&& func, atomic_t<u32>* wake_up = nullptr, bool track_emu_state = true, u64 stop_ctr = umax,
|
void CallFromMainThread(std::function<void()>&& func, atomic_t<u32>* wake_up = nullptr, bool track_emu_state = true, u64 stop_ctr = umax,
|
||||||
u32 line = __builtin_LINE(),
|
std::source_location src_loc = std::source_location::current()) const;
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* fun = __builtin_FUNCTION()) const;
|
|
||||||
|
|
||||||
// Blocking call from the GUI thread
|
// Blocking call from the GUI thread
|
||||||
void BlockingCallFromMainThread(std::function<void()>&& func,
|
void BlockingCallFromMainThread(std::function<void()>&& func, std::source_location src_loc = std::source_location::current()) const;
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* fun = __builtin_FUNCTION()) const;
|
|
||||||
|
|
||||||
enum class stop_counter_t : u64{};
|
enum class stop_counter_t : u64{};
|
||||||
|
|
||||||
|
@ -212,12 +205,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallFromMainThread(std::function<void()>&& func, stop_counter_t counter,
|
void CallFromMainThread(std::function<void()>&& func, stop_counter_t counter,
|
||||||
u32 line = __builtin_LINE(),
|
std::source_location src_loc = std::source_location::current()) const
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* fun = __builtin_FUNCTION()) const
|
|
||||||
{
|
{
|
||||||
CallFromMainThread(std::move(func), nullptr, true, static_cast<u64>(counter), line, col, file, fun);
|
CallFromMainThread(std::move(func), nullptr, true, static_cast<u64>(counter), src_loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostponeInitCode(std::function<void()>&& func)
|
void PostponeInitCode(std::function<void()>&& func)
|
||||||
|
|
|
@ -186,7 +186,7 @@ namespace psf
|
||||||
if (!static_cast<bool>(cond)) \
|
if (!static_cast<bool>(cond)) \
|
||||||
{ \
|
{ \
|
||||||
if (err != error::stream) \
|
if (err != error::stream) \
|
||||||
psf_log.error("Error loading PSF '%s': %s%s", filename, err, src_loc{__builtin_LINE(), __builtin_COLUMN(), __builtin_FILE(), __builtin_FUNCTION()}); \
|
psf_log.error("Error loading PSF '%s': %s%s", filename, err, std::source_location::current()); \
|
||||||
result.sfo.clear(); \
|
result.sfo.clear(); \
|
||||||
result.errc = err; \
|
result.errc = err; \
|
||||||
return result; \
|
return result; \
|
||||||
|
@ -392,7 +392,7 @@ namespace psf
|
||||||
return found->second.as_integer();
|
return found->second.as_integer();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_registry(const registry& psf, std::function<bool(bool ok, const std::string& key, const entry& value)> validate, u32 line, u32 col, const char* file, const char* func)
|
bool check_registry(const registry& psf, std::function<bool(bool ok, const std::string& key, const entry& value)> validate, std::source_location src_loc)
|
||||||
{
|
{
|
||||||
bool psf_ok = true;
|
bool psf_ok = true;
|
||||||
|
|
||||||
|
@ -413,12 +413,12 @@ namespace psf
|
||||||
{
|
{
|
||||||
if (value.type() == format::string)
|
if (value.type() == format::string)
|
||||||
{
|
{
|
||||||
psf_log.error("Entry '%s' is invalid: string='%s'.%s", key, value.as_string(), src_loc{line , col, file, func});
|
psf_log.error("Entry '%s' is invalid: string='%s'.%s", key, value.as_string(), src_loc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: Better logging of other types
|
// TODO: Better logging of other types
|
||||||
psf_log.error("Entry %s is invalid.%s", key, value.as_string(), src_loc{line , col, file, func});
|
psf_log.error("Entry %s is invalid.%s", key, value.as_string(), src_loc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,11 +103,7 @@ namespace psf
|
||||||
// Get integer value or default value
|
// Get integer value or default value
|
||||||
u32 get_integer(const registry& psf, std::string_view key, u32 def = 0);
|
u32 get_integer(const registry& psf, std::string_view key, u32 def = 0);
|
||||||
|
|
||||||
bool check_registry(const registry& psf, std::function<bool(bool ok, const std::string& key, const entry& value)> validate = {},
|
bool check_registry(const registry& psf, std::function<bool(bool ok, const std::string& key, const entry& value)> validate = {}, std::source_location src_loc = std::source_location::current());
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION());
|
|
||||||
|
|
||||||
// Assign new entry
|
// Assign new entry
|
||||||
inline void assign(registry& psf, std::string_view key, entry&& _entry)
|
inline void assign(registry& psf, std::string_view key, entry&& _entry)
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <compare>
|
#include <compare>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <bit>
|
#include <bit>
|
||||||
|
#include <source_location>
|
||||||
|
|
||||||
#if defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(__amd64__)
|
#if defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(__amd64__)
|
||||||
#define ARCH_X64 1
|
#define ARCH_X64 1
|
||||||
|
@ -908,47 +909,31 @@ const_str_t(const char8_t(&a)[Size]) -> const_str_t<Size - 1>;
|
||||||
|
|
||||||
using const_str = const_str_t<>;
|
using const_str = const_str_t<>;
|
||||||
|
|
||||||
struct src_loc
|
|
||||||
{
|
|
||||||
u32 line;
|
|
||||||
u32 col;
|
|
||||||
const char* file;
|
|
||||||
const char* func;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace fmt
|
namespace fmt
|
||||||
{
|
{
|
||||||
[[noreturn]] void raw_verify_error(const src_loc& loc, const char8_t* msg);
|
[[noreturn]] void raw_verify_error(std::source_location loc, const char8_t* msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
constexpr decltype(auto) ensure(T&& arg, const_str msg = const_str(),
|
constexpr decltype(auto) ensure(T&& arg, const_str msg = const_str(), std::source_location src_loc = std::source_location::current()) noexcept
|
||||||
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]]
|
if (std::forward<T>(arg)) [[likely]]
|
||||||
{
|
{
|
||||||
return std::forward<T>(arg);
|
return std::forward<T>(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::raw_verify_error({line, col, file, func}, msg);
|
fmt::raw_verify_error(src_loc, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename F> requires (std::is_invocable_v<F, T&&>)
|
template <typename T, typename F> requires (std::is_invocable_v<F, T&&>)
|
||||||
constexpr decltype(auto) ensure(T&& arg, F&& pred, const_str msg = const_str(),
|
constexpr decltype(auto) ensure(T&& arg, F&& pred, const_str msg = const_str(), std::source_location src_loc = std::source_location::current()) noexcept
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION()) noexcept
|
|
||||||
{
|
{
|
||||||
if (std::forward<F>(pred)(std::forward<T>(arg))) [[likely]]
|
if (std::forward<F>(pred)(std::forward<T>(arg))) [[likely]]
|
||||||
{
|
{
|
||||||
return std::forward<T>(arg);
|
return std::forward<T>(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::raw_verify_error({line, col, file, func}, msg);
|
fmt::raw_verify_error(src_loc, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// narrow() function details
|
// narrow() function details
|
||||||
|
@ -1024,16 +1009,12 @@ struct narrow_impl<From, To, std::enable_if_t<!std::is_same_v<std::common_type_t
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename To = void, typename From, typename = decltype(static_cast<To>(std::declval<From>()))>
|
template <typename To = void, typename From, typename = decltype(static_cast<To>(std::declval<From>()))>
|
||||||
[[nodiscard]] constexpr To narrow(const From& value,
|
[[nodiscard]] constexpr To narrow(const From& value, std::source_location src_loc = std::source_location::current())
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION())
|
|
||||||
{
|
{
|
||||||
// Narrow check
|
// Narrow check
|
||||||
if (narrow_impl<From, To>::test(value)) [[unlikely]]
|
if (narrow_impl<From, To>::test(value)) [[unlikely]]
|
||||||
{
|
{
|
||||||
fmt::raw_verify_error({line, col, file, func}, u8"Narrowing error");
|
fmt::raw_verify_error(src_loc, u8"Narrowing error");
|
||||||
}
|
}
|
||||||
|
|
||||||
return static_cast<To>(value);
|
return static_cast<To>(value);
|
||||||
|
@ -1041,11 +1022,7 @@ template <typename To = void, typename From, typename = decltype(static_cast<To>
|
||||||
|
|
||||||
// Returns u32 size() for container
|
// Returns u32 size() for container
|
||||||
template <typename CT> requires requires (const CT& x) { std::size(x); }
|
template <typename CT> requires requires (const CT& x) { std::size(x); }
|
||||||
[[nodiscard]] constexpr u32 size32(const CT& container,
|
[[nodiscard]] constexpr u32 size32(const CT& container, std::source_location src_loc = std::source_location::current())
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION())
|
|
||||||
{
|
{
|
||||||
// TODO: Support std::array
|
// TODO: Support std::array
|
||||||
constexpr bool is_const = std::is_array_v<std::remove_cvref_t<CT>>;
|
constexpr bool is_const = std::is_array_v<std::remove_cvref_t<CT>>;
|
||||||
|
@ -1057,38 +1034,30 @@ template <typename CT> requires requires (const CT& x) { std::size(x); }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return narrow<u32>(container.size(), line, col, file, func);
|
return narrow<u32>(container.size(), src_loc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CT, typename T> requires requires (CT&& x) { std::size(x); std::data(x); } || requires (CT&& x) { std::size(x); x.front(); }
|
template <typename CT, typename T> requires requires (CT&& x) { std::size(x); std::data(x); } || requires (CT&& x) { std::size(x); x.front(); }
|
||||||
[[nodiscard]] constexpr auto& at32(CT&& container, T&& index,
|
[[nodiscard]] constexpr auto& at32(CT&& container, T&& index, std::source_location src_loc = std::source_location::current())
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION())
|
|
||||||
{
|
{
|
||||||
// Make sure the index is within u32 range (TODO: downcast index properly with common_type)
|
// Make sure the index is within u32 range
|
||||||
const u32 idx = ::narrow<u32>(+index, line, 10001, file, func);
|
const std::make_unsigned_t<std::common_type_t<T>> idx = index;
|
||||||
const u32 csz = ::size32(container, line, 10002, file, func);
|
const u32 csz = ::size32(container, src_loc);
|
||||||
if (csz <= idx) [[unlikely]]
|
if (csz <= idx) [[unlikely]]
|
||||||
fmt::raw_verify_error({line, col, file, func}, u8"Out of range");
|
fmt::raw_verify_error(src_loc, u8"Out of range");
|
||||||
auto it = std::begin(std::forward<CT>(container));
|
auto it = std::begin(std::forward<CT>(container));
|
||||||
std::advance(it, idx);
|
std::advance(it, idx);
|
||||||
return *it;
|
return *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CT, typename T> requires requires (CT&& x, T&& y) { x.count(y); x.find(y); }
|
template <typename CT, typename T> requires requires (CT&& x, T&& y) { x.count(y); x.find(y); }
|
||||||
[[nodiscard]] constexpr auto& at32(CT&& container, T&& index,
|
[[nodiscard]] constexpr auto& at32(CT&& container, T&& index, std::source_location src_loc = std::source_location::current())
|
||||||
u32 line = __builtin_LINE(),
|
|
||||||
u32 col = __builtin_COLUMN(),
|
|
||||||
const char* file = __builtin_FILE(),
|
|
||||||
const char* func = __builtin_FUNCTION())
|
|
||||||
{
|
{
|
||||||
// Associative container
|
// Associative container
|
||||||
const auto found = container.find(std::forward<T>(index));
|
const auto found = container.find(std::forward<T>(index));
|
||||||
if (found == container.end()) [[unlikely]]
|
if (found == container.end()) [[unlikely]]
|
||||||
fmt::raw_verify_error({line, col, file, func}, u8"Out of range");
|
fmt::raw_verify_error(src_loc, u8"Out of range");
|
||||||
return found->second;
|
return found->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue