From 274de0e70d917382c5c14bb07db4774db6f45a87 Mon Sep 17 00:00:00 2001 From: q66 Date: Sat, 27 Jun 2015 02:38:58 +0100 Subject: [PATCH] add functional::EndianSwap,EndianSwapLil,EndianSwapBig (+ corresponding plain funcs) --- octa/functional.h | 82 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/octa/functional.h b/octa/functional.h index cf3a217..1a259da 100644 --- a/octa/functional.h +++ b/octa/functional.h @@ -6,6 +6,7 @@ #ifndef OCTA_FUNCTIONAL_H #define OCTA_FUNCTIONAL_H +#include "octa/platform.h" #include "octa/new.h" #include "octa/memory.h" #include "octa/utility.h" @@ -91,6 +92,87 @@ template BinaryNegate not2(const T &fn) { return BinaryNegate(fn); } +/* endian swap */ + +template::value +> struct EndianSwap; + +template +struct EndianSwap { + using Argument = T; + using Result = T; + T operator()(T v) { + union { T iv; uint16_t sv; } u; + u.iv = v; + u.sv = octa::endian_swap16(u.sv); + return u.iv; + } +}; + +template +struct EndianSwap { + using Argument = T; + using Result = T; + T operator()(T v) { + union { T iv; uint32_t sv; } u; + u.iv = v; + u.sv = octa::endian_swap32(u.sv); + return u.iv; + } +}; + +template +struct EndianSwap { + using Argument = T; + using Result = T; + T operator()(T v) { + union { T iv; uint64_t sv; } u; + u.iv = v; + u.sv = octa::endian_swap64(u.sv); + return u.iv; + } +}; + +template +T endian_swap(T x) { return EndianSwap()(x); } + +namespace detail { + template::value + > struct EndianSame; + + template + struct EndianSame { + using Argument = T; + using Result = T; + T operator()(T v) { return v; } + }; + template + struct EndianSame { + using Argument = T; + using Result = T; + T operator()(T v) { return v; } + }; + template + struct EndianSame { + using Argument = T; + using Result = T; + T operator()(T v) { return v; } + }; +} + +#if OCTA_BYTE_ORDER == OCTA_ENDIAN_LIL +template struct EndianSwapLil: octa::detail::EndianSame {}; +template struct EndianSwapBig: EndianSwap {}; +#else +template struct EndianSwapLil: EndianSwap {}; +template struct EndianSwapBig: octa::detail::EndianSame {}; +#endif + +template T endian_swap_lil(T x) { return EndianSwapLil()(x); } +template T endian_swap_big(T x) { return EndianSwapBig()(x); } + /* hash */ template struct ToHash {