parent
28ca58c0e9
commit
e58686c9df
|
@ -27,6 +27,27 @@
|
||||||
#include <byteswap.h>
|
#include <byteswap.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !__cpp_lib_endian
|
||||||
|
// Polyfill
|
||||||
|
#ifdef __BYTE_ORDER__
|
||||||
|
namespace std {
|
||||||
|
enum class endian {
|
||||||
|
little = __ORDER_LITTLE_ENDIAN__,
|
||||||
|
big = __ORDER_BIG_ENDIAN__,
|
||||||
|
native = __BYTE_ORDER__
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Hardcode to little endian for now
|
||||||
|
namespace std {
|
||||||
|
enum class endian { little = 0, big = 1, native = 0 };
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
// Check for mixed endian
|
||||||
|
static_assert((std::endian::native == std::endian::big) ||
|
||||||
|
(std::endian::native == std::endian::little));
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
||||||
#if XE_PLATFORM_WIN32
|
#if XE_PLATFORM_WIN32
|
||||||
|
@ -88,34 +109,46 @@ inline T byte_swap(T value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, std::endian E>
|
||||||
struct be {
|
struct endian_store {
|
||||||
be() = default;
|
endian_store() = default;
|
||||||
be(const T& src) : value(xe::byte_swap(src)) {} // NOLINT(runtime/explicit)
|
endian_store(const T& src) {
|
||||||
be(const be& other) { value = other.value; } // NOLINT(runtime/explicit)
|
if constexpr (std::endian::native == E) {
|
||||||
operator T() const { return xe::byte_swap(value); }
|
value = src;
|
||||||
|
} else {
|
||||||
|
value = xe::byte_swap(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endian_store(const endian_store& other) { value = other.value; }
|
||||||
|
operator T() const {
|
||||||
|
if constexpr (std::endian::native == E) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return xe::byte_swap(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
be<T>& operator+=(int a) {
|
endian_store<T, E>& operator+=(int a) {
|
||||||
*this = *this + a;
|
*this = *this + a;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
be<T>& operator-=(int a) {
|
endian_store<T, E>& operator-=(int a) {
|
||||||
*this = *this - a;
|
*this = *this - a;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
be<T>& operator++() {
|
endian_store<T, E>& operator++() {
|
||||||
*this += 1;
|
*this += 1;
|
||||||
return *this;
|
return *this;
|
||||||
} // ++a
|
} // ++a
|
||||||
be<T> operator++(int) {
|
endian_store<T, E> operator++(int) {
|
||||||
*this += 1;
|
*this += 1;
|
||||||
return (*this - 1);
|
return (*this - 1);
|
||||||
} // a++
|
} // a++
|
||||||
be<T>& operator--() {
|
endian_store<T, E>& operator--() {
|
||||||
*this -= 1;
|
*this -= 1;
|
||||||
return *this;
|
return *this;
|
||||||
} // --a
|
} // --a
|
||||||
be<T> operator--(int) {
|
endian_store<T, E> operator--(int) {
|
||||||
*this -= 1;
|
*this -= 1;
|
||||||
return (*this + 1);
|
return (*this + 1);
|
||||||
} // a--
|
} // a--
|
||||||
|
@ -123,6 +156,11 @@ struct be {
|
||||||
T value;
|
T value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using be = endian_store<T, std::endian::big>;
|
||||||
|
template <typename T>
|
||||||
|
using le = endian_store<T, std::endian::little>;
|
||||||
|
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
#endif // XENIA_BASE_BYTE_ORDER_H_
|
#endif // XENIA_BASE_BYTE_ORDER_H_
|
||||||
|
|
Loading…
Reference in New Issue