// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later /** * (c) 2014-2016 Alexandro Sanchez Bach. All rights reserved. * Released under GPL v2 license. Read LICENSE for more details. * Some modifications for using with shadps4 by georgemoralis */ #pragma once #include #include #include "common/types.h" namespace Common { /** * Native endianness */ template using NativeEndian = T; template class SwappedEndian { public: const T& Raw() const { return data; } T Swap() const { return std::byteswap(data); } void FromRaw(const T& value) { data = value; } void FromSwap(const T& value) { data = std::byteswap(value); } operator const T() const { return Swap(); } template explicit operator const SwappedEndian() const { SwappedEndian res; if (sizeof(T1) < sizeof(T)) { res.FromRaw(Raw() >> ((sizeof(T) - sizeof(T1)) * 8)); } else if (sizeof(T1) > sizeof(T)) { res.FromSwap(Swap()); } else { res.FromRaw(Raw()); } return res; } SwappedEndian& operator=(const T& right) { FromSwap(right); return *this; } SwappedEndian& operator=(const SwappedEndian& right) = default; template SwappedEndian& operator+=(T1 right) { return *this = T(*this) + right; } template SwappedEndian& operator-=(T1 right) { return *this = T(*this) - right; } template SwappedEndian& operator*=(T1 right) { return *this = T(*this) * right; } template SwappedEndian& operator/=(T1 right) { return *this = T(*this) / right; } template SwappedEndian& operator%=(T1 right) { return *this = T(*this) % right; } template SwappedEndian& operator&=(T1 right) { return *this = T(*this) & right; } template SwappedEndian& operator|=(T1 right) { return *this = T(*this) | right; } template SwappedEndian& operator^=(T1 right) { return *this = T(*this) ^ right; } template SwappedEndian& operator<<=(T1 right) { return *this = T(*this) << right; } template SwappedEndian& operator>>=(T1 right) { return *this = T(*this) >> right; } template SwappedEndian& operator+=(const SwappedEndian& right) { return *this = Swap() + right.Swap(); } template SwappedEndian& operator-=(const SwappedEndian& right) { return *this = Swap() - right.Swap(); } template SwappedEndian& operator*=(const SwappedEndian& right) { return *this = Swap() * right.Swap(); } template SwappedEndian& operator/=(const SwappedEndian& right) { return *this = Swap() / right.Swap(); } template SwappedEndian& operator%=(const SwappedEndian& right) { return *this = Swap() % right.Swap(); } template SwappedEndian& operator&=(const SwappedEndian& right) { return *this = Raw() & right.Raw(); } template SwappedEndian& operator|=(const SwappedEndian& right) { return *this = Raw() | right.Raw(); } template SwappedEndian& operator^=(const SwappedEndian& right) { return *this = Raw() ^ right.Raw(); } template SwappedEndian operator&(const SwappedEndian& right) const { return SwappedEndian{Raw() & right.Raw()}; } template SwappedEndian operator|(const SwappedEndian& right) const { return SwappedEndian{Raw() | right.Raw()}; } template SwappedEndian operator^(const SwappedEndian& right) const { return SwappedEndian{Raw() ^ right.Raw()}; } template bool operator==(T1 right) const { return (T1)Swap() == right; } template bool operator!=(T1 right) const { return !(*this == right); } template bool operator>(T1 right) const { return (T1)Swap() > right; } template bool operator<(T1 right) const { return (T1)Swap() < right; } template bool operator>=(T1 right) const { return (T1)Swap() >= right; } template bool operator<=(T1 right) const { return (T1)Swap() <= right; } template bool operator==(const SwappedEndian& right) const { return Raw() == right.Raw(); } template bool operator!=(const SwappedEndian& right) const { return !(*this == right); } template bool operator>(const SwappedEndian& right) const { return (T1)Swap() > right.Swap(); } template bool operator<(const SwappedEndian& right) const { return (T1)Swap() < right.Swap(); } template bool operator>=(const SwappedEndian& right) const { return (T1)Swap() >= right.Swap(); } template bool operator<=(const SwappedEndian& right) const { return (T1)Swap() <= right.Swap(); } SwappedEndian operator++(int) { SwappedEndian res = *this; *this += 1; return res; } SwappedEndian operator--(int) { SwappedEndian res = *this; *this -= 1; return res; } SwappedEndian& operator++() { *this += 1; return *this; } SwappedEndian& operator--() { *this -= 1; return *this; } private: T data; }; template using LittleEndian = std::conditional_t, SwappedEndian>; template using BigEndian = std::conditional_t, SwappedEndian>; } // namespace Common using u16_be = Common::BigEndian; using u32_be = Common::BigEndian; using u64_be = Common::BigEndian; using u16_le = Common::LittleEndian; using u32_le = Common::LittleEndian; using u64_le = Common::LittleEndian;