endian: refactor endian conversion

This commit is contained in:
Danny Robson 2018-05-19 18:06:14 +10:00
parent 7d315c8095
commit 7070607839

View File

@ -24,13 +24,6 @@
#include <type_traits> #include <type_traits>
namespace util { namespace util {
//-------------------------------------------------------------------------
// Uses the TIFF header values. Just because. Don't rely on this.
enum class endian : uint16_t {
BIG = 0x4D4D,
LITTLE = 0x4949,
};
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <typename T> template <typename T>
constexpr T constexpr T
@ -147,9 +140,52 @@ namespace util {
template <typename T> constexpr T ltoh (T v) { return v; } template <typename T> constexpr T ltoh (T v) { return v; }
#endif #endif
template <typename T> T btol (T t) { return bswap (t); }
template <typename T> T ltob (T t) { return bswap (t); }
namespace endian {
//---------------------------------------------------------------------
// Uses the TIFF header values. Just because. Don't rely on this.
enum class scheme : uint16_t {
BIG = 0x4D4D,
LITTLE = 0x4949,
big = BIG,
little = LITTLE,
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
native = little,
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
native = big
#else
#error Unhandled endianness
#endif
};
template <scheme DstV, scheme SrcV>
struct converter;
template <> struct converter<scheme::little,scheme::big> {
template <typename T>
static T convert (T t) { return btol (t); }
};
template <> struct converter<scheme::big,scheme::little> {
template <typename T>
static T convert (T t) { return ltob (t); }
};
template <scheme DstV, scheme SrcV, typename T>
T convert (T t)
{
return converter<DstV,SrcV>::convert (t);
}
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
struct from_endian { struct from_endian {
explicit from_endian (endian _endian): explicit from_endian (endian::scheme _endian):
src (_endian) src (_endian)
{ ; } { ; }
@ -168,7 +204,7 @@ namespace util {
else else
uint = v; uint = v;
uint = (src == endian::LITTLE) ? ltoh (uint) : btoh (uint); uint = (src == endian::scheme::LITTLE) ? ltoh (uint) : btoh (uint);
if (std::is_signed<T>::value) if (std::is_signed<T>::value)
return T (sint); return T (sint);
@ -176,7 +212,7 @@ namespace util {
return T (uint); return T (uint);
} }
endian src; endian::scheme src;
}; };
} }
#endif #endif