vm::ref improved (operators)

atomic operators fixed, vm::ptr operators improved
This commit is contained in:
Nekotekina 2015-06-15 14:37:01 +03:00
parent b7d967361d
commit d7cb5a6e9e
4 changed files with 137 additions and 46 deletions

View File

@ -190,42 +190,40 @@ public:
}
};
// Helper definitions
template<typename T, typename T2 = T> using if_integral_le_t = std::enable_if_t<std::is_integral<T>::value && std::is_integral<T2>::value, le_t<T>>;
template<typename T, typename T2 = T> using if_integral_be_t = std::enable_if_t<std::is_integral<T>::value && std::is_integral<T2>::value, be_t<T>>;
template<typename T, typename T2 = T> using if_arithmetic_le_t = std::enable_if_t<std::is_arithmetic<T>::value && std::is_arithmetic<T2>::value, le_t<T>>;
template<typename T, typename T2 = T> using if_arithmetic_be_t = std::enable_if_t<std::is_arithmetic<T>::value && std::is_arithmetic<T2>::value, be_t<T>>;
template<typename T> inline static if_arithmetic_le_t<T> operator ++(_atomic_base<le_t<T>>& left)
template<typename T> inline if_integral_le_t<T> operator ++(_atomic_base<le_t<T>>& left)
{
return left.from_subtype(sync_fetch_and_add(&left.sub_data, 1) + 1);
}
template<typename T> inline static if_arithmetic_le_t<T> operator --(_atomic_base<le_t<T>>& left)
template<typename T> inline if_integral_le_t<T> operator --(_atomic_base<le_t<T>>& left)
{
return left.from_subtype(sync_fetch_and_sub(&left.sub_data, 1) - 1);
}
template<typename T> inline static if_arithmetic_le_t<T> operator ++(_atomic_base<le_t<T>>& left, int)
template<typename T> inline if_integral_le_t<T> operator ++(_atomic_base<le_t<T>>& left, int)
{
return left.from_subtype(sync_fetch_and_add(&left.sub_data, 1));
}
template<typename T> inline static if_arithmetic_le_t<T> operator --(_atomic_base<le_t<T>>& left, int)
template<typename T> inline if_integral_le_t<T> operator --(_atomic_base<le_t<T>>& left, int)
{
return left.from_subtype(sync_fetch_and_sub(&left.sub_data, 1));
}
template<typename T, typename T2> inline static if_arithmetic_le_t<T, T2> operator +=(_atomic_base<le_t<T>>& left, T2 right)
template<typename T, typename T2> inline if_integral_le_t<T, T2> operator +=(_atomic_base<le_t<T>>& left, T2 right)
{
return left.from_subtype(sync_fetch_and_add(&left.sub_data, right) + right);
}
template<typename T, typename T2> inline static if_arithmetic_le_t<T, T2> operator -=(_atomic_base<le_t<T>>& left, T2 right)
template<typename T, typename T2> inline if_integral_le_t<T, T2> operator -=(_atomic_base<le_t<T>>& left, T2 right)
{
return left.from_subtype(sync_fetch_and_sub(&left.sub_data, right) - right);
}
template<typename T> inline static if_arithmetic_be_t<T> operator ++(_atomic_base<be_t<T>>& left)
template<typename T> inline if_integral_be_t<T> operator ++(_atomic_base<be_t<T>>& left)
{
be_t<T> result;
@ -237,7 +235,7 @@ template<typename T> inline static if_arithmetic_be_t<T> operator ++(_atomic_bas
return result;
}
template<typename T> inline static if_arithmetic_be_t<T> operator --(_atomic_base<be_t<T>>& left)
template<typename T> inline if_integral_be_t<T> operator --(_atomic_base<be_t<T>>& left)
{
be_t<T> result;
@ -249,7 +247,7 @@ template<typename T> inline static if_arithmetic_be_t<T> operator --(_atomic_bas
return result;
}
template<typename T> inline static if_arithmetic_be_t<T> operator ++(_atomic_base<be_t<T>>& left, int)
template<typename T> inline if_integral_be_t<T> operator ++(_atomic_base<be_t<T>>& left, int)
{
be_t<T> result;
@ -261,7 +259,7 @@ template<typename T> inline static if_arithmetic_be_t<T> operator ++(_atomic_bas
return result;
}
template<typename T> inline static if_arithmetic_be_t<T> operator --(_atomic_base<be_t<T>>& left, int)
template<typename T> inline if_integral_be_t<T> operator --(_atomic_base<be_t<T>>& left, int)
{
be_t<T> result;
@ -273,7 +271,7 @@ template<typename T> inline static if_arithmetic_be_t<T> operator --(_atomic_bas
return result;
}
template<typename T, typename T2> inline static if_arithmetic_be_t<T, T2> operator +=(_atomic_base<be_t<T>>& left, T2 right)
template<typename T, typename T2> inline if_integral_be_t<T, T2> operator +=(_atomic_base<be_t<T>>& left, T2 right)
{
be_t<T> result;
@ -285,7 +283,7 @@ template<typename T, typename T2> inline static if_arithmetic_be_t<T, T2> operat
return result;
}
template<typename T, typename T2> inline static if_arithmetic_be_t<T, T2> operator -=(_atomic_base<be_t<T>>& left, T2 right)
template<typename T, typename T2> inline if_integral_be_t<T, T2> operator -=(_atomic_base<be_t<T>>& left, T2 right)
{
be_t<T> result;

View File

@ -58,7 +58,7 @@ namespace vm
return{ convert_le_be<AT2>(vm::cast(m_addr)) };
}
explicit operator T*() const
template<typename T2, typename dummy = std::enable_if_t<std::is_convertible<T*, T2*>::value>> explicit operator T2*() const
{
return get_ptr();
}
@ -210,14 +210,20 @@ namespace vm
RT>;
}
// unary plus operator for vm::_ptr_base (always available)
template<typename T, typename AT> inline vm::_ptr_base<T, AT> operator +(const vm::_ptr_base<T, AT>& ptr)
{
return ptr;
}
// indirection operator for vm::_ptr_base
template<typename T, typename AT> vm::if_arithmetical_t<T, T&> operator *(const vm::_ptr_base<T, AT>& ptr)
template<typename T, typename AT> inline vm::if_arithmetical_t<T, T&> operator *(const vm::_ptr_base<T, AT>& ptr)
{
return vm::get_ref<T>(vm::cast(ptr.m_addr));
}
// postfix increment operator for vm::_ptr_base
template<typename T, typename AT> vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>> operator ++(vm::_ptr_base<T, AT>& ptr, int)
template<typename T, typename AT> inline vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>> operator ++(vm::_ptr_base<T, AT>& ptr, int)
{
const AT result = ptr.m_addr;
ptr.m_addr += sizeof32(T);
@ -225,14 +231,14 @@ template<typename T, typename AT> vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>>
}
// prefix increment operator for vm::_ptr_base
template<typename T, typename AT> vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>&> operator ++(vm::_ptr_base<T, AT>& ptr)
template<typename T, typename AT> inline vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>&> operator ++(vm::_ptr_base<T, AT>& ptr)
{
ptr.m_addr += sizeof32(T);
return ptr;
}
// postfix decrement operator for vm::_ptr_base
template<typename T, typename AT> vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>> operator --(vm::_ptr_base<T, AT>& ptr, int)
template<typename T, typename AT> inline vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>> operator --(vm::_ptr_base<T, AT>& ptr, int)
{
const AT result = ptr.m_addr;
ptr.m_addr -= sizeof32(T);
@ -240,40 +246,46 @@ template<typename T, typename AT> vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>>
}
// prefix decrement operator for vm::_ptr_base
template<typename T, typename AT> vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>&> operator --(vm::_ptr_base<T, AT>& ptr)
template<typename T, typename AT> inline vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>&> operator --(vm::_ptr_base<T, AT>& ptr)
{
ptr.m_addr -= sizeof32(T);
return ptr;
}
// addition assignment operator for vm::_ptr_base (pointer += integer)
template<typename T, typename AT> vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>&> operator +=(vm::_ptr_base<T, AT>& ptr, to_ne_t<AT> count)
template<typename T, typename AT> inline vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>&> operator +=(vm::_ptr_base<T, AT>& ptr, to_ne_t<AT> count)
{
ptr.m_addr += count * sizeof32(T);
return ptr;
}
// subtraction assignment operator for vm::_ptr_base (pointer -= integer)
template<typename T, typename AT> vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>&> operator -=(vm::_ptr_base<T, AT>& ptr, to_ne_t<AT> count)
template<typename T, typename AT> inline vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>&> operator -=(vm::_ptr_base<T, AT>& ptr, to_ne_t<AT> count)
{
ptr.m_addr -= count * sizeof32(T);
return ptr;
}
// addition operator for vm::_ptr_base (pointer + integer)
template<typename T, typename AT> vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>> operator +(const vm::_ptr_base<T, AT>& ptr, to_ne_t<AT> count)
template<typename T, typename AT> inline vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>> operator +(const vm::_ptr_base<T, AT>& ptr, to_ne_t<AT> count)
{
return{ convert_le_be<AT>(ptr.m_addr + count * sizeof32(T)) };
}
// addition operator for vm::_ptr_base (integer + pointer)
template<typename T, typename AT> inline vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>> operator +(to_ne_t<AT> count, const vm::_ptr_base<T, AT>& ptr)
{
return{ convert_le_be<AT>(ptr.m_addr + count * sizeof32(T)) };
}
// subtraction operator for vm::_ptr_base (pointer - integer)
template<typename T, typename AT> vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>> operator -(const vm::_ptr_base<T, AT>& ptr, to_ne_t<AT> count)
template<typename T, typename AT> inline vm::if_arithmetical_t<T, vm::_ptr_base<T, AT>> operator -(const vm::_ptr_base<T, AT>& ptr, to_ne_t<AT> count)
{
return{ convert_le_be<AT>(ptr.m_addr - count * sizeof32(T)) };
}
// pointer difference operator for vm::_ptr_base
template<typename T1, typename AT1, typename T2, typename AT2> std::enable_if_t<
template<typename T1, typename AT1, typename T2, typename AT2> inline std::enable_if_t<
!std::is_void<T1>::value &&
!std::is_void<T2>::value &&
!std::is_function<T1>::value &&

View File

@ -43,28 +43,25 @@ namespace vm
return get_ref();
}
//operator T() const
//{
// return get_ref();
//}
explicit operator T&() const
{
return get_ref();
}
// copy assignment operator
_ref_base& operator =(const _ref_base& right)
auto operator =(const _ref_base& right) -> decltype(std::declval<T&>() = std::declval<T>())
{
get_ref() = right.get_ref();
return *this;
return get_ref() = right.get_ref();
}
template<typename CT, typename AT2> std::enable_if_t<std::is_assignable<T&, CT>::value, const _ref_base&> operator =(const _ref_base<CT, AT2>& right) const
template<typename CT, typename AT2> auto operator =(const _ref_base<CT, AT2>& right) -> decltype(std::declval<T&>() = std::declval<CT>()) const
{
get_ref() = right.get_ref();
return *this;
return get_ref() = right.get_ref();
}
template<typename CT> std::enable_if_t<std::is_assignable<T&, CT>::value, const _ref_base&> operator =(const CT& right) const
template<typename CT> auto operator =(const CT& right) -> decltype(std::declval<T&>() = std::declval<CT>()) const
{
get_ref() = right;
return *this;
return get_ref() = right;
}
};
@ -108,6 +105,90 @@ namespace vm
using namespace ps3;
}
// postfix increment operator for vm::_ref_base
template<typename T, typename AT> inline auto operator ++(const vm::_ref_base<T, AT>& ref, int) -> decltype(std::declval<T&>()++)
{
return ref.get_ref()++;
}
// prefix increment operator for vm::_ref_base
template<typename T, typename AT> inline auto operator ++(const vm::_ref_base<T, AT>& ref) -> decltype(++std::declval<T&>())
{
return ++ref.get_ref();
}
// postfix decrement operator for vm::_ref_base
template<typename T, typename AT> inline auto operator --(const vm::_ref_base<T, AT>& ref, int) -> decltype(std::declval<T&>()--)
{
return ref.get_ref()--;
}
// prefix decrement operator for vm::_ref_base
template<typename T, typename AT> inline auto operator --(const vm::_ref_base<T, AT>& ref) -> decltype(--std::declval<T&>())
{
return --ref.get_ref();
}
// addition assignment operator for vm::_ref_base
template<typename T, typename AT, typename T2> inline auto operator +=(const vm::_ref_base<T, AT>& ref, const T2& right) -> decltype(std::declval<T&>() += std::declval<T2>())
{
return ref.get_ref() += right;
}
// subtraction assignment operator for vm::_ref_base
template<typename T, typename AT, typename T2> inline auto operator -=(const vm::_ref_base<T, AT>& ref, const T2& right) -> decltype(std::declval<T&>() -= std::declval<T2>())
{
return ref.get_ref() -= right;
}
// multiplication assignment operator for vm::_ref_base
template<typename T, typename AT, typename T2> inline auto operator *=(const vm::_ref_base<T, AT>& ref, const T2& right) -> decltype(std::declval<T&>() *= std::declval<T2>())
{
return ref.get_ref() *= right;
}
// division assignment operator for vm::_ref_base
template<typename T, typename AT, typename T2> inline auto operator /=(const vm::_ref_base<T, AT>& ref, const T2& right) -> decltype(std::declval<T&>() /= std::declval<T2>())
{
return ref.get_ref() /= right;
}
// modulo assignment operator for vm::_ref_base
template<typename T, typename AT, typename T2> inline auto operator %=(const vm::_ref_base<T, AT>& ref, const T2& right) -> decltype(std::declval<T&>() %= std::declval<T2>())
{
return ref.get_ref() %= right;
}
// bitwise AND assignment operator for vm::_ref_base
template<typename T, typename AT, typename T2> inline auto operator &=(const vm::_ref_base<T, AT>& ref, const T2& right) -> decltype(std::declval<T&>() &= std::declval<T2>())
{
return ref.get_ref() &= right;
}
// bitwise OR assignment operator for vm::_ref_base
template<typename T, typename AT, typename T2> inline auto operator |=(const vm::_ref_base<T, AT>& ref, const T2& right) -> decltype(std::declval<T&>() |= std::declval<T2>())
{
return ref.get_ref() |= right;
}
// bitwise XOR assignment operator for vm::_ref_base
template<typename T, typename AT, typename T2> inline auto operator ^=(const vm::_ref_base<T, AT>& ref, const T2& right) -> decltype(std::declval<T&>() ^= std::declval<T2>())
{
return ref.get_ref() ^= right;
}
// bitwise left shift assignment operator for vm::_ref_base
template<typename T, typename AT, typename T2> inline auto operator <<=(const vm::_ref_base<T, AT>& ref, const T2& right) -> decltype(std::declval<T&>() <<= std::declval<T2>())
{
return ref.get_ref() <<= right;
}
// bitwise right shift assignment operator for vm::_ref_base
template<typename T, typename AT, typename T2> inline auto operator >>=(const vm::_ref_base<T, AT>& ref, const T2& right) -> decltype(std::declval<T&>() >>= std::declval<T2>())
{
return ref.get_ref() >>= right;
}
// external specialization for is_be_t<> (true if AT's endianness is BE)
template<typename T, typename AT>

View File

@ -27,17 +27,17 @@ s32 UTF16stoUTF8s(vm::ptr<const char16_t> utf16, vm::ref<u32> utf16_len, vm::ptr
len = len + 1;
// validate character (TODO)
if (false)
{
utf16_len = utf16_len - i;
return SRCIllegal;
}
//if ()
//{
// utf16_len -= i;
// return SRCIllegal;
//}
if (utf8)
{
if (len > max_len)
{
utf16_len = utf16_len - i;
utf16_len -= i;
return DSTExhausted;
}