From fba15db34b6db88534633eddbb27962d04524d67 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Tue, 15 Jul 2014 19:44:39 +1000 Subject: [PATCH] endian: complete reimplementation Old implementation was overly verbose. We can just rely on gcc builtins as we can't actually build on anything else anyway. --- endian.cpp | 87 +----------------------------------------------------- endian.hpp | 79 ++++++++++++++++++++----------------------------- 2 files changed, 33 insertions(+), 133 deletions(-) diff --git a/endian.cpp b/endian.cpp index e7477aa8..55ce4548 100644 --- a/endian.cpp +++ b/endian.cpp @@ -14,92 +14,7 @@ * You should have received a copy of the GNU General Public License * along with libgim. If not, see . * - * Copyright 2010 Danny Robson + * Copyright 2010-2014 Danny Robson */ #include "endian.hpp" - -#include -#include - -using std::is_fundamental; -using std::is_unsigned; - -#ifdef WORDS_BIGENDIAN -/* Big endian doesn't need swapping */ -template -T hton (T val) { - static_assert (is_fundamental (), "hton implementation assumes fundamental types"); - static_assert (is_unsigned (), "hton implementation does not handle signed"); - return val; -} - -template -T ntoh (T val) { - static_assert (is_fundamental (), "ntoh implementation assumes fundamental types"); - static_assert (is_unsigned (), "ntoh implementation does not handle signed"); - return val; -} - -template <> uint8_t hton ( uint8_t); -template <> uint16_t hton (uint16_t); -template <> uint32_t hton (uint32_t); -template <> uint64_t hton (uint64_t); - -template <> uint8_t ntoh ( uint8_t); -template <> uint16_t ntoh (uint16_t); -template <> uint32_t ntoh (uint32_t); -template <> uint64_t ntoh (uint64_t); - -#else - -static void -byte_swap (uint8_t *restrict dst, uint8_t *restrict src, size_t len) { - for (unsigned int i = 0; i < len; ++i) - dst[len - i - 1] = src[i]; -} - - -template -T -hton (T i) { - // Unsure if this will really be sensible for non-intrinsic types, or types larger than 8 bytes. - static_assert (is_fundamental ::value, "hton implementation assumes fundamental types"); - static_assert (is_unsigned ::value, "hton implementation does not handle signed"); - - T swapped; - byte_swap (reinterpret_cast (&swapped), - reinterpret_cast (&i), - sizeof (T)); - return swapped; -} - - -template -T -ntoh (T i) { - // Unsure if this will really be sensible for non-intrinsic types, or types larger than 8 bytes. - static_assert (is_fundamental ::value, "ntoh implementation assumes fundamental types"); - static_assert (is_unsigned ::value, "ntoh implementation does not handle signed"); - - T swapped; - byte_swap (reinterpret_cast (&swapped), - reinterpret_cast (&i), - sizeof (T)); - return swapped; -} - -template <> uint8_t hton (uint8_t i) { return i; } -template <> uint8_t ntoh (uint8_t i) { return i; } - -template uint16_t ntoh (uint16_t); -template uint32_t ntoh (uint32_t); -template uint64_t ntoh (uint64_t); - -template uint16_t hton (uint16_t); -template uint32_t hton (uint32_t); -template uint64_t hton (uint64_t); - -#endif - - diff --git a/endian.hpp b/endian.hpp index bfd905ea..00c62ef1 100644 --- a/endian.hpp +++ b/endian.hpp @@ -14,69 +14,54 @@ * You should have received a copy of the GNU General Public License * along with libgim. If not, see . * - * Copyright 2010 Danny Robson + * Copyright 2010-2014 Danny Robson */ #ifndef __UTIL_ENDIAN_HPP #define __UTIL_ENDIAN_HPP -#include "platform.hpp" - #include -enum { - ENDIAN_BIG, - ENDIAN_LITTLE -}; +//----------------------------------------------------------------------------- +template +constexpr T +bswap (T); + +template <> constexpr uint8_t bswap ( uint8_t v) { return v; } +template <> constexpr uint16_t bswap (uint16_t v) { return __builtin_bswap16 (v); } +template <> constexpr uint32_t bswap (uint32_t v) { return __builtin_bswap32 (v); } +template <> constexpr uint64_t bswap (uint64_t v) { return __builtin_bswap64 (v); } -constexpr uint8_t hton (uint8_t h) { return h; } -constexpr uint8_t ntoh (uint8_t n) { return n; } - - -constexpr uint16_t hton (uint16_t h) { - return ((h & 0xFF00) >> 8) | - ((h & 0x00FF) << 8); +//----------------------------------------------------------------------------- +template +constexpr T +identity (T &&v) { + return v; } -constexpr uint16_t ntoh (uint16_t n) - { return hton (n); } +//----------------------------------------------------------------------------- +#if defined(WORDS_BIGENDIAN) +template constexpr T hton (T v) { return v; } +template constexpr T ntoh (T v) { return v; } -constexpr uint32_t hton (uint32_t h) { -#if defined(COMPILER_GCC) - return __builtin_bswap32 (h); +template constexpr T htob (T v) { return v; } +template constexpr T htol (T v) { return bswap (v); } + +template constexpr T btoh (T v) { return v; } +template constexpr T ltoh (T v) { return bswap (v); } #else - return (h & 0xFF000000U) >> 24 | - (h & 0x00FF0000U) >> 8 | - (h & 0x0000FF00U) << 8 | - (h & 0x000000FFU) << 24; +template constexpr T hton (T v) { return bswap (v); } +template constexpr T ntoh (T v) { return bswap (v); } + +template constexpr T htob (T v) { return bswap (v); } +template constexpr T htol (T v) { return v; } + +template constexpr T btoh (T v) { return bswap (v); } +template constexpr T ltoh (T v) { return v; } #endif -} -constexpr uint32_t ntoh (uint32_t n) - { return hton (n); } - - -constexpr uint64_t hton (uint64_t h) { -#if defined(COMPILER_GCC) - return __builtin_bswap64 (h); -#else - return (h & 0xFF00000000000000UL) >> 56 | - (h & 0x00FF000000000000UL) >> 40 | - (h & 0x0000FF0000000000UL) >> 24 | - (h & 0x000000FF00000000UL) >> 8 | - (h & 0x00000000FF000000UL) << 8 | - (h & 0x0000000000FF0000UL) << 24 | - (h & 0x000000000000FF00UL) << 40 | - (h & 0x00000000000000FFUL) << 56; -#endif -} - - -constexpr uint64_t ntoh (uint64_t n) - { return hton (n); } - #endif