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> inline if_integral_le_t<T> operator ++(_atomic_base<le_t<T>>& left)
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)
{ {
return left.from_subtype(sync_fetch_and_add(&left.sub_data, 1) + 1); 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); 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)); 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)); 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); 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); 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; be_t<T> result;
@ -237,7 +235,7 @@ template<typename T> inline static if_arithmetic_be_t<T> operator ++(_atomic_bas
return result; 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; be_t<T> result;
@ -249,7 +247,7 @@ template<typename T> inline static if_arithmetic_be_t<T> operator --(_atomic_bas
return result; 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; be_t<T> result;
@ -261,7 +259,7 @@ template<typename T> inline static if_arithmetic_be_t<T> operator ++(_atomic_bas
return result; 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; be_t<T> result;
@ -273,7 +271,7 @@ template<typename T> inline static if_arithmetic_be_t<T> operator --(_atomic_bas
return result; 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; be_t<T> result;
@ -285,7 +283,7 @@ template<typename T, typename T2> inline static if_arithmetic_be_t<T, T2> operat
return result; 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; be_t<T> result;

View File

@ -58,7 +58,7 @@ namespace vm
return{ convert_le_be<AT2>(vm::cast(m_addr)) }; 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(); return get_ptr();
} }
@ -210,14 +210,20 @@ namespace vm
RT>; 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 // 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)); return vm::get_ref<T>(vm::cast(ptr.m_addr));
} }
// postfix increment operator for vm::_ptr_base // 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; const AT result = ptr.m_addr;
ptr.m_addr += sizeof32(T); 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 // 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); ptr.m_addr += sizeof32(T);
return ptr; return ptr;
} }
// postfix decrement operator for vm::_ptr_base // 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; const AT result = ptr.m_addr;
ptr.m_addr -= sizeof32(T); 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 // 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); ptr.m_addr -= sizeof32(T);
return ptr; return ptr;
} }
// addition assignment operator for vm::_ptr_base (pointer += integer) // 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); ptr.m_addr += count * sizeof32(T);
return ptr; return ptr;
} }
// subtraction assignment operator for vm::_ptr_base (pointer -= integer) // 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); ptr.m_addr -= count * sizeof32(T);
return ptr; return ptr;
} }
// addition operator for vm::_ptr_base (pointer + integer) // 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)) }; return{ convert_le_be<AT>(ptr.m_addr + count * sizeof32(T)) };
} }
// subtraction operator for vm::_ptr_base (pointer - integer) // 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)) }; return{ convert_le_be<AT>(ptr.m_addr - count * sizeof32(T)) };
} }
// pointer difference operator for vm::_ptr_base // 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<T1>::value &&
!std::is_void<T2>::value && !std::is_void<T2>::value &&
!std::is_function<T1>::value && !std::is_function<T1>::value &&

View File

@ -43,28 +43,25 @@ namespace vm
return get_ref(); return get_ref();
} }
//operator T() const explicit operator T&() const
//{ {
// return get_ref(); return get_ref();
//} }
// copy assignment operator // 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 get_ref() = right.get_ref();
return *this;
} }
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 get_ref() = right.get_ref();
return *this;
} }
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 get_ref() = right;
return *this;
} }
}; };
@ -108,6 +105,90 @@ namespace vm
using namespace ps3; 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) // external specialization for is_be_t<> (true if AT's endianness is BE)
template<typename T, typename AT> 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; len = len + 1;
// validate character (TODO) // validate character (TODO)
if (false) //if ()
{ //{
utf16_len = utf16_len - i; // utf16_len -= i;
return SRCIllegal; // return SRCIllegal;
} //}
if (utf8) if (utf8)
{ {
if (len > max_len) if (len > max_len)
{ {
utf16_len = utf16_len - i; utf16_len -= i;
return DSTExhausted; return DSTExhausted;
} }