rpcsx/rpcs3/Emu/Memory/vm_ref.h

189 lines
3.9 KiB
C
Raw Normal View History

#pragma once
namespace vm
{
2016-02-01 22:52:49 +01:00
template<typename T, typename AT>
class _ptr_base;
2016-02-01 22:52:49 +01:00
template<typename T, typename AT = u32>
class _ref_base
{
AT m_addr;
2015-02-01 08:09:24 +01:00
static_assert(!std::is_pointer<T>::value, "vm::_ref_base<> error: invalid type (pointer)");
static_assert(!std::is_reference<T>::value, "vm::_ref_base<> error: invalid type (reference)");
static_assert(!std::is_function<T>::value, "vm::_ref_base<> error: invalid type (function)");
static_assert(!std::is_void<T>::value, "vm::_ref_base<> error: invalid type (void)");
2014-09-01 18:16:44 +02:00
public:
using type = T;
using addr_type = std::remove_cv_t<AT>;
_ref_base() = default;
_ref_base(const _ref_base&) = default;
2016-05-13 16:01:48 +02:00
_ref_base(vm::addr_t addr)
: m_addr(addr)
2015-06-13 16:48:21 +02:00
{
}
2016-05-13 16:01:48 +02:00
addr_type addr() const
2015-06-13 16:48:21 +02:00
{
return m_addr;
2015-06-13 16:48:21 +02:00
}
T& get_ref() const
{
2016-02-01 22:52:49 +01:00
return *static_cast<T*>(vm::base(vm::cast(m_addr, HERE)));
2015-06-13 16:48:21 +02:00
}
// convert to vm pointer
vm::_ptr_base<T, u32> ptr() const
2015-06-13 16:48:21 +02:00
{
2016-05-13 16:01:48 +02:00
return vm::cast(m_addr, HERE);
2015-06-13 16:48:21 +02:00
}
2016-02-01 22:52:49 +01:00
operator simple_t<T>() const
{
2015-06-13 16:48:21 +02:00
return get_ref();
}
operator T&() const
{
return get_ref();
}
T& operator =(const _ref_base& right)
{
return get_ref() = right.get_ref();
}
2016-02-01 22:52:49 +01:00
T& operator =(const simple_t<T>& right) const
{
return get_ref() = right;
}
2015-06-15 18:02:16 +02:00
decltype(auto) operator ++(int)
{
return get_ref()++;
2014-09-01 23:22:07 +02:00
}
decltype(auto) operator ++()
2014-09-01 23:22:07 +02:00
{
return ++get_ref();
2014-09-01 23:22:07 +02:00
}
decltype(auto) operator --(int)
2014-09-01 23:22:07 +02:00
{
return get_ref()--;
}
decltype(auto) operator --()
{
return --get_ref();
}
2016-02-01 22:52:49 +01:00
template<typename T2>
decltype(auto) operator +=(const T2& right)
{
return get_ref() += right;
}
2016-02-01 22:52:49 +01:00
template<typename T2>
decltype(auto) operator -=(const T2& right)
{
return get_ref() -= right;
}
2016-02-01 22:52:49 +01:00
template<typename T2>
decltype(auto) operator *=(const T2& right)
{
return get_ref() *= right;
}
2016-02-01 22:52:49 +01:00
template<typename T2>
decltype(auto) operator /=(const T2& right)
{
return get_ref() /= right;
}
2016-02-01 22:52:49 +01:00
template<typename T2>
decltype(auto) operator %=(const T2& right)
{
return get_ref() %= right;
}
2016-02-01 22:52:49 +01:00
template<typename T2>
decltype(auto) operator &=(const T2& right)
{
return get_ref() &= right;
}
2016-02-01 22:52:49 +01:00
template<typename T2>
decltype(auto) operator |=(const T2& right)
{
return get_ref() |= right;
}
2016-02-01 22:52:49 +01:00
template<typename T2>
decltype(auto) operator ^=(const T2& right)
{
return get_ref() ^= right;
}
2016-02-01 22:52:49 +01:00
template<typename T2>
decltype(auto) operator <<=(const T2& right)
{
return get_ref() <<= right;
}
2016-02-01 22:52:49 +01:00
template<typename T2>
decltype(auto) operator >>=(const T2& right)
{
return get_ref() >>= right;
2014-09-01 23:22:07 +02:00
}
};
// Native endianness reference to LE data
template<typename T, typename AT = u32> using refl = _ref_base<to_le_t<T>, AT>;
// Native endianness reference to BE data
template<typename T, typename AT = u32> using refb = _ref_base<to_be_t<T>, AT>;
// BE reference to LE data
template<typename T, typename AT = u32> using brefl = _ref_base<to_le_t<T>, to_be_t<AT>>;
// BE reference to BE data
template<typename T, typename AT = u32> using brefb = _ref_base<to_be_t<T>, to_be_t<AT>>;
// LE reference to LE data
template<typename T, typename AT = u32> using lrefl = _ref_base<to_le_t<T>, to_le_t<AT>>;
// LE reference to BE data
template<typename T, typename AT = u32> using lrefb = _ref_base<to_be_t<T>, to_le_t<AT>>;
2018-02-09 15:49:37 +01:00
inline namespace ps3_
{
// default reference for PS3 HLE functions (Native endianness reference to BE data)
template<typename T, typename AT = u32> using ref = refb<T, AT>;
// default reference for PS3 HLE structures (BE reference to BE data)
2015-03-09 02:57:50 +01:00
template<typename T, typename AT = u32> using bref = brefb<T, AT>;
}
2015-06-13 16:48:21 +02:00
}
2016-02-01 22:52:49 +01:00
// Change AT endianness to BE/LE
template<typename T, typename AT, bool Se>
struct to_se<vm::_ref_base<T, AT>, Se>
{
using type = vm::_ref_base<T, typename to_se<AT, Se>::type>;
};
// Forbid formatting
template<typename T, typename AT>
struct fmt_unveil<vm::_ref_base<T, AT>, void>
2015-01-13 18:38:32 +01:00
{
static_assert(!sizeof(T), "vm::_ref_base<>: ambiguous format argument");
};